ZJOI2006书架

追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\n",Splay.size[Splay.c[pos[x]][0]]-1);break;
81         case 'Q':printf("%d\n",Splay.val[Splay.find(Splay.rt,x+1)]);break;
82         }
83     }
84     return 0;
85 }
View Code

 

转载于:https://www.cnblogs.com/zcysky/p/6843982.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值