bzoj 1367

来源:互联网 发布:火星情报局 淘宝模特 编辑:程序博客网 时间:2024/06/06 04:04

05年的论文题,好像两篇论文里都有

可并堆维护中位数

然而论文最后的二分法没看懂QAQ网上也找不到二分的方法

所以只好用左偏树水一水了

#include<iostream>#include<cstdio>#include<cstring>#include<queue>using namespace std;typedef long long ll;const int N=1000000+5;queue<int>rubbish;struct Heapnode{int l,r,v,d,sz;void clear(){l=r=v=d=sz=0;}}tr[N];int merge(int x,int y){if(!x||!y)return x+y;if(tr[x].v<tr[y].v)swap(x,y);tr[x].r=merge(tr[x].r,y);if(tr[tr[x].r].d>tr[tr[x].l].d)swap(tr[x].l,tr[x].r);if(!tr[x].r)tr[x].d=0;else tr[x].d=tr[tr[x].r].d+1;tr[x].sz=tr[tr[x].l].sz+tr[tr[x].r].sz+1;return x;}int pop(int x){int l=tr[x].l,r=tr[x].r;tr[x].clear();rubbish.push(x);return merge(l,r);}int sz;int newheap(int v){int tmp;if(rubbish.empty())tmp=++sz;else tmp=rubbish.front(),rubbish.pop();tr[tmp]=(Heapnode){0,0,v,0,1};return tmp;}int push(int x,int v){return merge(x,newheap(v));}int m,s[N],l[N],r[N];void refresh(){while(m>1&&tr[s[m-1]].v>=tr[s[m]].v){m--;s[m]=merge(s[m],s[m+1]);r[m]=r[m+1];if((r[m]-l[m]+2)/2<tr[s[m]].sz)s[m]=pop(s[m]);}}int a[N];int iabs(int x){return x<0?-x:x;}int main(){//freopen("a.in","r",stdin);//freopen("a.out","w",stdout);int n;scanf("%d",&n);for(int i=1;i<=n;i++){scanf("%d",&a[i]);a[i]-=i;s[++m]=newheap(a[i]);l[m]=r[m]=i;refresh();}ll ans=0;for(int i=1;i<=m;i++)for(int j=l[i];j<=r[i];j++)ans+=iabs(a[j]-tr[s[i]].v);printf("%lld\n",ans);return 0;}


0 0
原创粉丝点击