Splay又写挫了。。。。。。。。
回头复习一下维修数列和LCT吧,不然Splay真不会写了。
#include<iostream> #include<cstdio> #include<cstring> using namespace std; const int N=80000+5; const int inf=1e9; int id[N],ch[N][2],fa[N],a[N],root,sz[N],node,key[N],n,m; inline void pushup(int x){sz[x]=sz[ch[x][0]]+sz[ch[x][1]]+1;} inline void rotate(int x,int &k){ int y=fa[x],z=fa[y],l=ch[y][1]==x,r=l^1; if(y==k)k=x; else ch[z][ch[z][1]==y]=x; fa[x]=z;fa[y]=x;fa[ch[x][r]]=y; ch[y][l]=ch[x][r];ch[x][r]=y; pushup(y);pushup(x); } inline void splay(int x,int &k){ while(x!=k){ int y=fa[x],z=fa[y]; if(y!=k){ if(ch[y][0]==x^ch[z][0]==y)rotate(x,k); else rotate(y,k); } rotate(x,k); } } void build(int l,int r,int f){ if(l>r)return; int mid=l+r>>1,now=mid,last=f; if(l==r){ sz[now]=1; }else build(l,mid-1,mid),build(mid+1,r,mid); key[now]=a[mid];fa[now]=last;pushup(now); ch[last][mid>=f]=now; } int kth(int x,int k){ int r=sz[ch[x][0]]+1; if(r==k)return x; else if(k<r)return kth(ch[x][0],k); else return kth(ch[x][1],k-r); } void del(int k){ int x,y,z; x=kth(root,k-1);y=kth(root,k+1); splay(x,root);splay(y,ch[x][1]); z=ch[y][0];ch[y][0]=0;fa[z]=sz[z]=0; pushup(y);pushup(x); } void move(int k,int val){ int x,y,z=id[k],rank; splay(z,root);rank=sz[ch[z][0]]+1; del(rank); if(val==inf)x=kth(root,n),y=kth(root,n+1); else if(val==-inf)x=kth(root,1),y=kth(root,2); else x=kth(root,rank+val-1),y=kth(root,rank+val); splay(x,root);splay(y,ch[x][1]); sz[z]=1;fa[z]=y;ch[y][0]=z; pushup(y);pushup(x); } int main(){ scanf("%d%d",&n,&m); for(int i=2;i<=n+1;i++){ scanf("%d",&a[i]);id[a[i]]=i; } build(1,n+2,0);root=n+3>>1; char opt[10];int s,t; while(m--){ scanf("%s%d",opt,&s); switch(opt[0]){ case 'T':move(s,-inf);break; case 'B':move(s,inf);break; case 'I':scanf("%d",&t);move(s,t);break; case 'A':splay(id[s],root);printf("%d\n",sz[ch[id[s]][0]]-1);break; case 'Q':printf("%d\n",key[kth(root,s+1)]);break; } } return 0; }