BZOJ 3506 robotic sort (splay)

来源:互联网 发布:mac口红黄皮色号推荐 编辑:程序博客网 时间:2024/05/20 20:05

description


input

输入共两行,第一行为一个整数N,N表示物品的个数,1<=N<=100000。第二行为N个用空格隔开的正整数,表示N个物品最初排列的编号。

output

输出共一行,N个用空格隔开的正整数P1,P2,P3…Pn,(1 < = Pi < = N),Pi表示第i次操作前第i小的物品所在的位置。 注意:如果第i次操作前,第i小的物品己经在正确的位置Pi上,我们将区间[Pi,Pi]反转(单个物品)。

sample input 1

6
3 4 5 1 6 2

sample output 1

4 6 4 5 6 6

sample input 2

4
3 3 2 1

sample output 2

4 2 4 4

#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>using namespace std;#define inf (1e9)#define maxn (100000+5)int N,root,top;int v[maxn],size[maxn],pos[maxn],mi[maxn],ans[maxn],s[maxn],f[maxn],c[maxn][2];bool rev[maxn];struct node{int v,pos;bool operator < (const node &b)const{return pos<b.pos;}}a[maxn];bool cmp(node a,node b){return a.v<b.v||(a.v==b.v&&a.pos<b.pos);}void update(int x){int l=c[x][0],r=c[x][1];mi[x]=v[x]; pos[x]=x;if(mi[l]<mi[x]){mi[x]=mi[l]; pos[x]=pos[l];}if(mi[r]<mi[x]){mi[x]=mi[r]; pos[x]=pos[r];}size[x]=size[l]+size[r]+1;}void built(int L,int R,int F){if(L>R)return ;if(L==R){f[L]=F; pos[L]=L; size[L]=1;v[L]=mi[L]=a[L].v;if(L<F)c[F][0]=L;else c[F][1]=L;return ;}int mid=(L+R)>>1;built(L,mid-1,mid); built(mid+1,R,mid);f[mid]=F; v[mid]=a[mid].v; update(mid);if(mid<F)c[F][0]=mid;else c[F][1]=mid;}void push_down(int x){int l=c[x][0],r=c[x][1];rev[x]^=1; rev[l]^=1; rev[r]^=1;swap(c[x][0],c[x][1]);}void rotate(int x,int &k){//旋转 int y=f[x],z=f[y],l,r;if(c[y][0]==x)l=0; else l=1; r=l^1;if(y==k)k=x;else{if(c[z][0]==y)c[z][0]=x;else c[z][1]=x;}f[x]=z; f[y]=x; f[c[x][r]]=y;c[y][l]=c[x][r]; c[x][r]=y;update(y); update(x);}void splay(int x,int &k){top=0; s[++top]=x;for(int i=x;f[i];i=f[i])s[++top]=f[i];for(int i=top;i;i--)if(rev[s[i]])push_down(s[i]);while(x!=k){int y=f[x],z=f[y];if(y!=k){if((c[y][0]==x)==(c[z][0]==y))rotate(y,k);else rotate(x,k);}rotate(x,k);}}int find(int x,int rx){if(rev[x])push_down(x);int l=c[x][0],r=c[x][1];if(size[l]+1==rx)return x;else if(size[l]>=rx)return find(l,rx);else return find(r,rx-size[l]-1);}int ask(int L,int R){int x=find(root,L),y=find(root,R+2);splay(x,root); splay(y,c[x][1]);int z=c[y][0];return pos[z];}void reverse(int L,int R){//反向int x=find(root,L),y=find(root,R+2);splay(x,root); splay(y,c[x][1]);int z=c[y][0];rev[z]^=1;}void input(){scanf("%d",&N);for(int i=2;i<=N+1;i++){scanf("%d",&a[i].v);a[i].pos=i;}a[1].v=a[N+2].v=inf;mi[0]=inf;}void solve(){//离散化 discretizationsort(a+2,a+N+2,cmp);for(int i=2;i<=N+1;i++)a[i].v=i-1;sort(a+2,a+N+2);built(1,N+2,0);root=(N+3)>>1;for(int i=1;i<=N;i++){int temp=ask(i,N);splay(temp,root);ans[i]=size[c[temp][0]];reverse(i,ans[i]);}for(int i=1;i<=N;i++){printf("%d",ans[i]);if(i!=N)printf(" ");}}int main(){input();solve();return 0;}



0 0
原创粉丝点击