结论见论文:http://wenku.baidu.com/link?url=t55yGX-UkUdEXBhpvBwuzjKP16F7lFl0RKSVVBBW5zXWRB7rRXvLLj1jM-pzhbH834hQl0KKT4va247VmSepsGDSrYF1E3le_WpnKc2xfCi
可并堆维护中位数 当size>tot/2+1时弹出堆顶最大值
把递增化为不降 只需减个下标即可
PS random heap 这次表现不佳
#include<cstdio> #include<cstdlib> #include<algorithm> using namespace std; typedef long long ll; inline char nc() { static char buf[100000],*p1=buf,*p2=buf; if (p1==p2) { p2=(p1=buf)+fread(buf,1,100000,stdin); if (p1==p2) return EOF; } return *p1++; } inline void read(ll &x) { char c=nc(),b=1; for (;!(c>='0' && c<='9');c=nc()) if (c=='-') b=-1; for (x=0;c>='0' && c<='9';x=x*10+c-'0',c=nc()); x*=b; } const int N=1000005; inline int ran() { static int x=31253125; x+=(x<<4)+1; return x&65536; } struct node{ ll key; node *l,*r; }nodes[N]; node *M(node *p,node *q){ return (!p||!q)?(p?p:q):(p->key<q->key?M(q,p):((ran()?p->l=M(p->l,q):p->r=M(p->r,q)),p)); } ll n,a[N]; int tot,st[N],ed[N],size[N],num[N]; node *root[N]; int main() { freopen("t.in","r",stdin); freopen("t.out","w",stdout); read(n); for (int i=1;i<=n;i++) read(a[i]),a[i]-=i,nodes[i].key=a[i]; for (int i=1;i<=n;i++) { tot++; st[tot]=i; ed[tot]=i; size[tot]=1; num[tot]=1; root[tot]=nodes+i; while (tot>=2 && root[tot]->key<root[tot-1]->key) { ed[tot-1]=ed[tot]; size[tot-1]+=size[tot]; num[tot-1]+=num[tot]; root[tot-1]=M(root[tot-1],root[tot]); tot--; while (size[tot]>num[tot]/2+1) root[tot]=M(root[tot]->l,root[tot]->r),size[tot]--; } } ll ans=0; for (int i=1;i<=tot;i++) for (int j=st[i];j<=ed[i];j++) ans+=abs(root[i]->key-a[j]); printf("%lld\n",ans); return 0; }