bzoj 3506: [Cqoi2014]排序机械臂
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; #define N 110000 #define inf 0x6fffffff int root; struct P{ int x,y; bool operator<(P a)const{ if(x!=a.x)return x<a.x; return y<a.y; } }val[N],mi[N]; int n,a[N]; int l[N],rev[N],pre[N],ch[N][2],siz[N]; inline void up(int x){ if(mi[ch[x][0]]<mi[ch[x][1]]){ l[x]=l[ch[x][0]]; mi[x]=mi[ch[x][0]]; }else{ l[x]=1+l[ch[x][1]]+siz[ch[x][0]]; mi[x]=mi[ch[x][1]]; } if(val[x]<mi[x]){ mi[x]=val[x]; l[x]=siz[ch[x][0]]+1; } siz[x]=siz[ch[x][0]]+siz[ch[x][1]]+1; } inline void revs(int x){ if(!x)return; rev[x]^=1; swap(ch[x][0],ch[x][1]); l[x]=siz[x]+1-l[x]; } inline void down(int x){ if(rev[x]){ rev[x]=0; revs(ch[x][0]); revs(ch[x][1]); } } void rotate(int x){ int y=pre[x],z=pre[y]; down(y); down(x); int k=x==ch[y][0]; pre[ch[y][!k]=ch[x][k]]=y; pre[ch[x][k]=y]=x; pre[x]=z; if(z)ch[z][ch[z][1]==y]=x; else root=x; up(y); } void splay(int x,int f){ int y,z; for(;pre[x]!=f;){ y=pre[x],z=pre[y]; if(z==f)rotate(x); else if((ch[z][1]==y)==(ch[y][1]==x))rotate(y),rotate(x); else rotate(x),rotate(x); } up(x); } void select(int k,int f){ int x=root; while(siz[ch[x][0]]+1!=k){ down(x); if(k<=siz[ch[x][0]])x=ch[x][0]; else k-=siz[ch[x][0]]+1,x=ch[x][1]; } down(x); splay(x,f); } int tot=2; int build(int f,int L,int R){ if(L>R)return 0; int x=++tot; int mid=(L+R)>>1; val[x]=(P){a[mid],mid}; pre[x]=f; ch[x][0]=build(x,L,mid-1); ch[x][1]=build(x,mid+1,R); up(x); return x; } void solv(int x){ int k=l[root]; printf("%d ",k+x-1); select(1,0); select(k,1); revs(ch[ch[1][1]][0]); select(k-1,0); select(k+1,root); ch[ch[root][1]][0]=0; splay(ch[root][1],0); } int main(){ scanf("%d",&n); for(int i=1;i<=n;i++)scanf("%d",&a[i]); mi[0]=(P){inf,0}; val[1]=mi[1]=mi[0]; val[2]=mi[2]=mi[0]; ch[1][1]=2; pre[2]=1; root=1; ch[2][0]=build(2,1,n); up(2); up(1); for(int i=0;i<n;i++)solv(i); }