51nod1482

题解:

发现是一个环,而环的题目有一些就是要转化成为链

首先找到一个最高点,中间断开

然后当作一条链来做

代码:

#include<cstdio>
#include<algorithm>
#define fo(i,a,b) for(i=a;i<=b;i++)
#define fd(i,a,b) for(i=a;i>=b;i--)
using namespace std;
typedef long long ll;
const int N=1000000+10;
int a[N],b[N],left[N],right[N],same[N],sta[N],bz[N];
int i,j,k,l,t,n,m,mx,top;
ll ans;
int read()
{
    int x=0;
    char ch=getchar();
    while (ch<'0'||ch>'9') ch=getchar();
    while (ch>='0'&&ch<='9')
     {
        x=x*10+ch-'0';
        ch=getchar();
     }
    return x;
}
int main()
{
    n=read();
    fo(i,1,n)
     {
        a[i]=read();
        if (!mx||a[i]>a[mx]) mx=i;
     }
    fo(i,mx,n) b[++top]=a[i];
    fo(i,1,mx-1) b[++top]=a[i];
    fo(i,1,n) a[i]=b[i];
    top=0;
    fo(i,2,n)
     {
        while (top&&a[i]>=a[sta[top]]) top--;
        left[i]=sta[top];
        sta[++top]=i;
     }
    top=0;
    sta[0]=n+1;
    fd(i,n,2)
     {
        while (top&&a[i]>=a[sta[top]])
         {
            if (a[i]==a[sta[top]]) same[i]=same[sta[top]]+1;
            top--;
         }
        right[i]=sta[top];
        sta[++top]=i;
     }
    fo(i,2,n)
     {
        if (left[i]>0) ans++;
        if (right[i]<=n) ans++;
        ans+=(ll)same[i];
     }
    mx=0;
    fo(i,2,n)
     {
        if (mx<=a[i]) bz[i]=1;
        mx=max(mx,a[i]);
     }
    mx=0;
    fd(i,n,2)
     {
        if (mx<=a[i]) bz[i]=1;
        mx=max(mx,a[i]);
     }
    fo(i,2,n) ans+=bz[i];
    printf("%I64d
",ans);
}
原文地址:https://www.cnblogs.com/xuanyiming/p/7570562.html