題目概述
給出
解題報告
對於這道題,我們可以將
如果
對於
示例程序
#include<cstdio>
#include<cctype>
#include<algorithm>
typedef long long LL;
using namespace std;
const int maxn=1e6;
int n,v[maxn+5],ro[maxn+5],son[maxn+5][2],dis[maxn+5];
int tot,L[maxn+5],R[maxn+5],si[maxn+5];LL ans;
#define Eoln(x) ((x)==10||(x)==13||(x)==EOF)
inline char readc(){
static char buf[100000],*l=buf,*r=buf;
if (l==r) r=(l=buf)+fread(buf,1,100000,stdin);
if (l==r) return EOF;return *l++;
}
inline int readi(int &x){
int tot=0,f=1;char ch=readc(),lst='+';
while (!isdigit(ch)) {if (ch==EOF) return EOF;lst=ch;ch=readc();}
if (lst=='-') f=-f;
while (isdigit(ch)) tot=(tot<<3)+(tot<<1)+ch-48,ch=readc();
return x=tot*f,Eoln(ch);
}
int Merge(int a,int b){
if (!a||!b) return a+b;if (v[a]<v[b]) swap(a,b);
int &l=son[a][0],&r=son[a][1];
r=Merge(r,b);if (dis[l]<dis[r]) swap(l,r);
return dis[a]=dis[r]+1,a;
}
#define Pop(ID) ro[ID]=Merge(son[ro[ID]][0],son[ro[ID]][1]),si[ID]--
inline int absi(int x) {if (x<0) return -x;return x;}
int main(){
freopen("program.in","r",stdin);
freopen("program.out","w",stdout);
readi(n);dis[0]=-1;for (int i=1;i<=n;i++) readi(v[i]),v[i]-=i;
for (int i=1;i<=n;i++){
ro[++tot]=i;L[tot]=i;R[tot]=i;si[tot]=1;
while (tot>1&&v[ro[tot-1]]>v[ro[tot]]){
tot--;ro[tot]=Merge(ro[tot],ro[tot+1]);
R[tot]=R[tot+1];si[tot]+=si[tot+1];
while (si[tot]>(R[tot]-L[tot]>>1)+1) Pop(tot);
}
}
for (int t=1;t<=tot;t++)
for (int i=L[t];i<=R[t];i++)
ans+=absi(v[i]-v[ro[t]]);
return printf("%lld\n",ans),0;
}