1. 程式人生 > >bzoj1552 [Cerc2007]robotic sort

bzoj1552 [Cerc2007]robotic sort

題目描述:

題解:

一道非常裸的splay。

程式碼:

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define N 100050
inline int rd()
{
    int f = 1,c = 0;char ch = getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='
9'){c=10*c+ch-'0';ch=getchar();} return f*c; } int n,p[N]; struct Pair { int x,id; }pr[N]; bool cmp(Pair a,Pair b) { if(a.x!=b.x)return a.x<b.x; return a.id<b.id; } struct Splay { int siz[N],fa[N],ch[N][2],rt; bool res[N]; void update(int x) { siz[x] = siz[ch[x][0
]]+siz[ch[x][1]]+1; } void reser(int x) { res[x]^=1; swap(ch[x][0],ch[x][1]); } void pushdown(int x) { if(res[x]) { reser(ch[x][0]); reser(ch[x][1]); res[x]=0; } } int get_kth(int x,int k) { pushdown(x);
int tmp = siz[ch[x][0]]; if(k<=tmp)return get_kth(ch[x][0],k); else if(k==tmp+1)return x; else return get_kth(ch[x][1],k-1-tmp); } int get_rank(int x) { if(x==rt)return siz[ch[x][0]]+1; if(x==ch[fa[x]][0])return get_rank(fa[x])-1-siz[ch[x][1]]; else return get_rank(fa[x])+1+siz[ch[x][0]]; } int build(int l,int r,int f) { if(l>r)return 0; int mid = (l+r)>>1; int x = p[mid]; fa[x] = f; ch[x][0] = build(l,mid-1,x); ch[x][1] = build(mid+1,r,x); update(x); return x; } void rotate(int x) { int y = fa[x],z = fa[y],k = (ch[y][1]==x); ch[y][k] = ch[x][!k],fa[ch[x][!k]] = y; ch[x][!k] = y,fa[y] = x; ch[z][ch[z][1]==y] = x,fa[x] = z; update(y),update(x); } int st[N],tl; void down(int x) { tl=1,st[1]=x; while(x)st[++tl]=x,x=fa[x]; while(tl)pushdown(st[tl]),tl--; } void splay(int x,int goal) { down(x); while(fa[x]!=goal) { int y = fa[x],z = fa[y]; if(z!=goal) (ch[y][1]==x)^(ch[z][1]==y)?rotate(x):rotate(y); rotate(x); } if(!goal)rt=x; } int deal(int x) { x++; down(x); int ret = get_rank(x); int rk1 = x,rk2 = ret,y; if(rk1>rk2)swap(rk1,rk2); rk1--,rk2++; x = get_kth(rt,rk1),y = get_kth(rt,rk2); splay(x,0),splay(y,x); reser(ch[y][0]); return ret-1; } }tr; int main() { n=rd(); for(int i=1;i<=n;i++) pr[i].x=rd(),pr[i].id=i; sort(pr+1,pr+1+n,cmp); for(int i=1;i<=n;i++) p[pr[i].id+1]=i+1; p[1]=1,p[n+2]=n+2; tr.rt = tr.build(1,n+2,0); for(int i=1;i<=n;i++) { int ans = tr.deal(i); printf("%d ",ans); } puts(""); return 0; }