http://www.lydsy.com/JudgeOnline/problem.php?id=1367

/**************************************************************
Problem: 1367
User: 1349367067
Language: C++
Result: Accepted
Time:7092 ms
Memory:28616 kb
****************************************************************/

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int n;
struct Node
{
int x,dis,size;
Node *l,*r;
void clear()
{
l=r=NULL;
dis=0;size=1;
}
}a[1000011];
bool check_dis(Node *A)
{
if (A->r==NULL) return false;
if (A->l==NULL) return true;
return (A->r->dis>A->l->dis);

}
Node *merge(Node *A,Node *B)
{
if (A==NULL) return B;
if (B==NULL) return A;
if (A->x<B->x) swap(A,B);
A->r=merge(A->r,B);
if (check_dis(A)) swap(A->l,A->r);
if (A->r==NULL) A->dis=0;
else A->dis=A->r->dis+1;
A->size=1;
if (A->l!=NULL) A->size+=A->l->size;
if (A->r!=NULL) A->size+=A->r->size;
return A;
}
Node *Q[1000011];
int Qs[1000011];
int num=0;
void fix(int i,int n)
{

//cout<<n<<"**"<<endl;
//system("pause");
while (Q[i]->size>(n+1)/2)
{
//cout<<Q[i]->size<<endl;
//system("pause");
Q[i]=merge(Q[i]->l,Q[i]->r);

}
}
inline int abs(int x) {return x<0?(-x):x;}
void init()
{
for (int i=1;i<=n;i++)
{
a[i].clear();
scanf("%d",&a[i].x);
a[i].x-=i;
}
num=1;Q[1]=&a[1];Qs[0]=0;Qs[1]=1;
for (int i=2;i<=n;i++)
{
num++;
Q[num]=&a[i];Qs[num]=i;
while (num>1&&Q[num]->x<Q[num-1]->x)
{
Q[num-1]=merge(Q[num],Q[num-1]);

//cout<<num<<" "<<Qs[num]<<" "<<Qs[num-1]<<endl;
Qs[num-1]=Qs[num];num--;
//cout<<num<<"OO"<<endl;
fix(num,Qs[num]-Qs[num-1]);

//system("pause");

}
}
long long ans=0ll;
for (int i=1;i<=num;i++)
{
for (int j=Qs[i-1]+1;j<=Qs[i];j++)
{
ans+=abs(a[j].x-Q[i]->x);
}
}
//cout<<"*"<<num<<endl;
//for (int i=1;i<=num;i++)
//    cout<<Qs[i]<<"*"<<(Q[i]->x)<<" ";
//cout<<endl;
printf("%lld\n",ans);

}
int main()
{
scanf("%d",&n);
init();

return 0;
}
View Code