[Baltic2004]sequence

IOI2005国集队论文上的例[神仙]题……

具体论证看论文吧233

#include <bits/stdc++.h>
using namespace std;
int N,M;
long long ans;
int val[1000005],size[1000005],a[1000005],cnt,rt[1000005],l[1000005],r[1000005];
int Tree[1000005][2],fa[1000005],dis[1000005];
int merge(int x,int y){
    if (x==0||y==0)
      return x+y;
    if (val[x]<val[y])
      swap(x,y);
    Tree[x][0]=merge(y,Tree[x][0]);
    size[x]=size[Tree[x][0]]+size[Tree[x][1]]+1;
    fa[Tree[x][0]]=x;
    if (dis[Tree[x][1]]<dis[Tree[x][0]])
    swap(Tree[x][1],Tree[x][0]);
    dis[x]=dis[Tree[x][0]]+1;
    return x;
}
int main()
{
    scanf("%d",&N);
    for (int i=1;i<=N;i++){scanf("%d",&a[i]);    a[i]-=i;}
    int cnt=0;
    for (int i=1;i<=N;i++){
        val[i]=a[i];
        size[i]=1;
        Tree[i][0]=Tree[i][1]=dis[i]=0;
        cnt++;
        rt[cnt]=i;
        l[cnt]=r[cnt]=i;
        while (cnt>1&&val[rt[cnt]]<val[rt[cnt-1]]){
            cnt--;
            rt[cnt]=merge(rt[cnt],rt[cnt+1]);
            r[cnt]=r[cnt+1];
            while (2*size[rt[cnt]]>r[cnt]-l[cnt]+2)
            rt[cnt]=merge(Tree[rt[cnt]][1],Tree[rt[cnt]][0]);
        }
    }
    for (int i=1;i<=cnt;i++){
        long long qwq=val[rt[i]];
        for (int j=l[i];j<=r[i];j++)
            ans+=1ll*abs(qwq-a[j]);
    }
    cout<<ans;
    return 0;
}
原文地址:https://www.cnblogs.com/si--nian/p/10949946.html