bzoj 1861
splay裸题嘛...
直接按书的编号顺序建splay,然后维护即可
把移动位置变成插入和删除
#include <cstdio> #include <cmath> #include <cstring> #include <cstdlib> #include <iostream> #include <algorithm> #include <queue> #include <stack> using namespace std; int ch[80005][2]; int f[80005]; int a[80005]; int siz[80005]; char s[15]; int rot,tot; int n,m; void update(int rt) { siz[rt]=siz[ch[rt][0]]+siz[ch[rt][1]]+1; } void rotate(int x) { int y=f[x],z=f[y],k=(ch[y][1]==x); ch[z][ch[z][1]==y]=x,f[x]=z; ch[y][k]=ch[x][!k],f[ch[x][!k]]=y; ch[x][!k]=y,f[y]=x; update(y),update(x); } void splay(int x,int ed) { while(f[x]!=ed) { int y=f[x],z=f[y]; if(z!=ed) { if((ch[y][1]==x)^(ch[z][1]==y))rotate(x); else rotate(y); } rotate(x); } if(!ed)rot=x; } int buildtree(int l,int r,int fa) { if(l==r){siz[a[l]]=1;f[a[l]]=a[fa];return a[l];} int mid=(l+r)>>1; f[a[mid]]=a[fa]; if(l<mid)ch[a[mid]][0]=buildtree(l,mid-1,mid); if(r>mid)ch[a[mid]][1]=buildtree(mid+1,r,mid); update(a[mid]); return a[mid]; } int get_pre(int x) { splay(x,0); int l=ch[x][0]; while(ch[l][1])l=ch[l][1]; return l; } int get_sub(int x) { splay(x,0); int r=ch[x][1]; while(ch[r][0])r=ch[r][0]; return r; } void del(int l,int r) { splay(l,0),splay(r,l); f[ch[r][0]]=0,ch[r][0]=0; } void ins(int l,int r,int v) { splay(l,0),splay(r,l); ch[r][0]=v,f[v]=r,siz[v]=1; update(r),update(l); } void push_top(int x) { int fr=get_pre(x),ed=get_sub(x); del(fr,ed); int ffr=n+1,eed=get_sub(ffr); ins(ffr,eed,x); } void push_down(int x) { int fr=get_pre(x),ed=get_sub(x); del(fr,ed); int eed=n+2,ffr=get_pre(eed); ins(ffr,eed,x); } void push_up(int x) { int fr=get_pre(x),ed=get_sub(x); del(fr,ed); int ffr=get_pre(fr); ins(ffr,fr,x); } void push_back(int x) { int fr=get_pre(x),ed=get_sub(x); del(fr,ed); int eed=get_sub(ed); ins(ed,eed,x); } void up_and_down(int x) { int T; scanf("%d",&T); if(T==-1)push_up(x); else if(T==1)push_back(x); } void query_sum(int x) { splay(x,0); printf("%d\n",siz[ch[x][0]]-1); } int query_num(int rt,int k) { if(siz[ch[rt][0]]>=k)return query_num(ch[rt][0],k); else if(k>siz[ch[rt][0]]+1)return query_num(ch[rt][1],k-1-siz[ch[rt][0]]); else return rt; } void Query_num(int x) { printf("%d\n",query_num(rot,x+1)); } int main() { scanf("%d%d",&n,&m); for(int i=2;i<=n+1;i++)scanf("%d",&a[i]); a[1]=n+1,a[n+2]=n+2; rot=buildtree(1,n+2,0); while(m--) { int x,T; scanf("%s%d",s,&x); if(s[0]=='T')push_top(x); else if(s[0]=='B')push_down(x); else if(s[0]=='I')up_and_down(x); else if(s[0]=='A')query_sum(x); else Query_num(x); } return 0; }