bzoj 1552: [Cerc2007]robotic sort
1552: [Cerc2007]robotic sort
Time Limit: 5 Sec Memory Limit: 64 MBSubmit: 1198 Solved: 457
[Submit][Status][Discuss]
Description
Input
输入共两行,第一行为一个整数N,N表示物品的个数,1<=N<=100000。
第二行为N个用空格隔开的正整数,表示N个物品最初排列的编号。
Output
输出共一行,N个用空格隔开的正整数P1,P2,P3…Pn,Pi表示第i次操作前第i小的物品所在的位置。
注意:如果第i次操作前,第i小的物品己经在正确的位置Pi上,我们将区间[Pi,Pi]反转(单个物品)。
Sample Input
6
3 4 5 1 6 2
3 4 5 1 6 2
Sample Output
4 6 4 5 6 6
HINT
Source
splay区间反转
#include<cstdio> #include<algorithm> using namespace std; #define INF 0x7fffffff int n; const int maxn = 100020; struct Data{ int a,pos; bool operator < (const Data & q)const { if(q.a==a)return pos<q.pos; else return a<q.a; } }l[maxn]; int mn[maxn],size[maxn],root,data[maxn],ch[maxn][2],mnpos[maxn]; int rev[maxn],fa[maxn]; inline void pushdown(int x) { rev[x]=0; rev[ch[x][0]]^=1; rev[ch[x][1]]^=1; swap(ch[ch[x][0]][0],ch[ch[x][0]][1]); swap(ch[ch[x][1]][0],ch[ch[x][1]][1]); } inline void pushup(int x) { mn[x]=min(data[x],min(mn[ch[x][1]],mn[ch[x][0]])); if(mn[x]==data[x])mnpos[x]=x; else if(mn[x]==mn[ch[x][0]])mnpos[x]=mnpos[ch[x][0]]; else mnpos[x]=mnpos[ch[x][1]]; size[x]=size[ch[x][0]]+size[ch[x][1]]+1; } inline int getkth(int k,int rt) { if(rev[rt])pushdown(rt); if(k==size[ch[rt][0]]+1)return rt; if(k<size[ch[rt][0]]+1)return getkth(k,ch[rt][0]); else getkth(k-size[ch[rt][0]]-1,ch[rt][1]); } inline int son(int x){ return ch[fa[x]][1]==x; } void rotate(int x) { int y=fa[x],z=fa[y],b=son(x),c=son(y),a=ch[x][!b]; if(z)ch[z][c]=x;else root=x;fa[x]=z; if(a)fa[a]=y;ch[y][b]=a; ch[x][!b]=y;fa[y]=x; pushup(y),pushup(x); } void splay(int &x,int i) { while(fa[x]!=i) { int y=fa[x],z=fa[y]; if(z==i){ rotate(x); }else { if(rev[z])pushdown(z);if(rev[y])pushdown(y);if(rev[x])pushdown(x); if(son(x)==son(y)) { rotate(y),rotate(x); } else { rotate(x);rotate(x); } } } } int getmnpos(int l,int r) { int ll=getkth(l-1,root); int rr=getkth(r+1,root); splay(ll,0); splay(rr,ll); return mnpos[ch[rr][0]]; } inline void reverse(int l,int r) { int ll=getkth(l-1,root),rr=getkth(r+1,root),p; splay(ll,0);splay(rr,ll); p=ch[rr][0];rev[p]^=1; swap(ch[p][0],ch[p][1]); } int main() { scanf("%d",&n); for(int i=2;i<=n+1;i++) scanf("%d",&l[i].a),l[i].pos=i; sort(l+2,l+n+2); for(int i=2;i<=n+1;i++)data[l[i].pos]=i; for(int i=0;i<=n+2;i++)mn[i]=INF; data[0]=data[1]=data[n+2]=INF;root=1; for(int i=1;i<=n+2;i++) { fa[i]=i-1; ch[i][1]=i+1; } ch[n+2][1]=0; for(int i=n+2;i>=1;i--) { pushup(i); } for(int i=1;i<=n;i++) { int po=getmnpos(i+1,n+1); splay(po,0); printf("%d",size[ch[po][0]]); reverse(i+1,size[ch[po][0]]+1); if(i!=n)printf(" "); } return 0; }