追yql做题记录的时候做到的……一道Splay模版题……
啊LCT写久了都有点忘了Splay了(什么奇怪的逻辑?)
其实说白了五个操作:
1、 将某元素置顶:将元素旋到根,然后将左子树合并到该元素的后继
2、 将某元素置底:将元素旋到根,然后将右子树合并到该元素的前驱
3、 将某元素提前/滞后1位:直接与该元素的前驱/后继交换位置及信息
4、 询问指定元素排名:将元素旋到根,输出size-1
5、 询问指定排名元素:在树上find
不好,我……我发现……我还在写数据结构!
1 #include<bits/stdc++.h> 2 #define N 80005 3 #define inf 1000000007 4 using namespace std; 5 int n,m,a[N],sz,pos[N]; 6 struct Splay_Tree{ 7 int c[N][2],fa[N],dep[N],size[N],val[N],rt; 8 inline void pushup(int x){size[x]=size[c[x][0]]+size[c[x][1]]+1;} 9 inline void rotate(int x,int &k){ 10 int y=fa[x],z=fa[y],l,r; 11 if(c[y][0]==x)l=0;else l=1;r=l^1; 12 if(y==k)k=x; 13 else {if(c[z][0]==y)c[z][0]=x;else c[z][1]=x;} 14 fa[x]=z;fa[y]=x;fa[c[x][r]]=y; 15 c[y][l]=c[x][r];c[x][r]=y; 16 pushup(y);pushup(x); 17 } 18 inline void splay(int x,int &k){ 19 while(k!=x){ 20 int y=fa[x],z=fa[y]; 21 if(y!=k){ 22 if((c[z][0]==y)^(c[y][0]==x))rotate(x,k); 23 else rotate(y,k); 24 }rotate(x,k); 25 } 26 } 27 void build(int l,int r,int f){ 28 if(l>r)return; 29 int now=l,last=f; 30 if(l==r){ 31 val[l]=a[l];size[l]=1;fa[l]=f; 32 if(l<f)c[f][0]=l;else c[f][1]=l; 33 } 34 int mid=(l+r)>>1; 35 build(l,mid-1,mid);build(mid+1,r,mid); 36 val[mid]=a[mid];fa[mid]=f;pushup(mid); 37 if(mid<f)c[f][0]=mid;else c[f][1]=mid; 38 } 39 int find(int k,int x){ 40 int l=c[k][0],r=c[k][1]; 41 if(size[l]+1==x)return k; 42 else if(size[l]>=x)return find(l,x); 43 else return find(r,x-size[l]-1); 44 } 45 void del(int k){ 46 int x=find(rt,k-1),y=find(rt,k+1),z; 47 splay(x,rt);splay(y,c[x][1]); 48 z=c[y][0];c[y][0]=0;fa[z]=size[z]=0; 49 pushup(y);pushup(x); 50 } 51 void move(int k,int v){ 52 int x,y,z=pos[k],rk; 53 splay(z,rt);rk=size[c[z][0]]+1; 54 del(rk); 55 if(v==inf)x=find(rt,n),y=find(rt,n+1); 56 else if(v==-inf)x=find(rt,1),y=find(rt,2); 57 else x=find(rt,rk+v-1),y=find(rt,rk+v); 58 splay(x,rt);splay(y,c[x][1]); 59 size[z]=1;fa[z]=y;c[y][0]=z; 60 pushup(y);pushup(x); 61 } 62 }Splay; 63 inline int read(){ 64 int f=1,x=0;char ch; 65 do{ch=getchar();if(ch=='-')f=-1;}while(ch<'0'||ch>'9'); 66 do{x=x*10+ch-'0';ch=getchar();}while(ch>='0'&&ch<='9'); 67 return f*x; 68 } 69 int main(){ 70 n=read();m=read(); 71 for(int i=2;i<=n+1;i++)a[i]=read(),pos[a[i]]=i; 72 Splay.build(1,n+2,0);Splay.rt=(n+3)>>1; 73 char s[20];int x,y; 74 while(m--){ 75 scanf("%s",s);x=read(); 76 switch(s[0]){ 77 case 'T':Splay.move(x,-inf);break; 78 case 'B':Splay.move(x,inf);break; 79 case 'I':y=read();Splay.move(x,y);break; 80 case 'A':Splay.splay(pos[x],Splay.rt);printf("%d ",Splay.size[Splay.c[pos[x]][0]]-1);break; 81 case 'Q':printf("%d ",Splay.val[Splay.find(Splay.rt,x+1)]);break; 82 } 83 } 84 return 0; 85 }