splay学习笔记

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<string>
  4 #include<cstring>
  5 #include<cstdlib>
  6 using namespace std;
  7 const int N=100010;
  8 const int INF=0x3f3f3f3f;
  9 int son[N][2],fa[N],size[N],cnt[N],key[N],root,sz,n,op,x;
 10 #define ls son[x][0]
 11 #define rs son[x][1]
 12 inline void clear(int x){son[x][1]=son[x][0]=fa[x]=size[x]=cnt[x]=key[x]=0;return ;}
 13 inline bool get(int x){return son[fa[x]][1]==x;}
 14 inline void update(int x){
 15     if(x){
 16         size[x]=cnt[x];
 17         if(ls)size[x]+=size[ls];
 18         if(rs)size[x]+=size[rs];
 19     }
 20     return ;
 21 }
 22 inline void rotate(int x){
 23     int y=fa[x],z=fa[y],k=get(x);
 24     son[y][k]=son[x][k^1];fa[son[y][k]]=y;
 25     fa[x]=z;son[x][k^1]=y;fa[y]=x;
 26     if(z)son[z][son[z][1]==y]=x;
 27     update(y);update(x);return ;
 28 }
 29 inline void splay(int x){//double rotate
 30     for(int f;(f=fa[x]);rotate(x))
 31         if(fa[f])
 32             rotate((get(x)==get(f))?f:x);
 33     root=x;
 34 }
 35 inline void insert(int val){
 36     if(!root){root=++sz;size[sz]=cnt[sz]=1;key[sz]=val;son[sz][1]=son[sz][0]=fa[sz]=0;return ;}
 37     int now=root,f=0;
 38     while(1){
 39         if(key[now]==val){cnt[now]++;update(now);update(f);splay(now);return ;}
 40         f=now;now=son[now][key[now]<val];
 41         if(!now){
 42             now=++sz;son[f][key[f]<val]=sz;fa[sz]=f;key[sz]=val;
 43             size[sz]=cnt[sz]=1;son[sz][1]=son[sz][0]=0;
 44             update(f);splay(sz);return ;
 45         }
 46     }
 47 }
 48 int find(int x,int val){
 49     if(key[x]==val)return x;
 50     if(key[x]>val)return find(ls,val);
 51     if(key[x]<val)return find(rs,val);
 52 }
 53 inline int Rank (int x ) {
 54     splay(find(root,x));
 55     return size[son[root][0]]+1;
 56 }
 57 inline int Kth(int x,int k){
 58     if(size[ls]>=k)return Kth(ls,k);
 59     if(size[ls]+cnt[x]>=k)return key[x];
 60     else return Kth(rs,k-size[ls]-cnt[x]);
 61 }
 62 inline int Pre(int x,int val){
 63     if(!x)return -INF;
 64     if(key[x]<val)return max(key[x],Pre(rs,val));
 65     if(key[x]>=val)return Pre(ls,val);
 66 }
 67 inline int Nxt(int x,int val){
 68     if(!x)return INF;
 69     if(key[x]>val)return min(key[x],Nxt(ls,val));
 70     if(key[x]<=val)return Nxt(rs,val);
 71 }
 72 inline void Del(int val){
 73     splay(find(root,val));int old=root;
 74     if(cnt[root]>1){cnt[root]--;update(root);return;}
 75     if(!son[root][1]&&!son[root][0]){clear(root);root=0;return ;}
 76     if(!son[root][1]){root=son[root][0];fa[root]=0;update(root);clear(old);return ;}
 77     if(!son[root][0]){root=son[root][1];fa[root]=0;update(root);clear(old);return ;}
 78     splay(find(root,Pre(root,val)));
 79     son[root][1]=son[old][1];fa[son[old][1]]=root;
 80     clear(old);update(root);return ;
 81 }
 82 int main()
 83 {
 84     scanf("%d",&n);
 85     while(n--){
 86         scanf("%d%d",&op,&x);
 87         switch(op){
 88             case 1:insert(x);break;
 89             case 2:Del(x);break;
 90             case 3:printf("%d\n",Rank(x));break;
 91             case 4:printf("%d\n",Kth(root,x));break;
 92             case 5:printf("%d\n",Pre(root,x));break;
 93             case 6:printf("%d\n",Nxt(root,x));break;
 94         }
 95     }
 96     return 0;
 97 }
 98 
 99 
100 /*update的其他操作 
101         sum[x]=sum[ls]+sum[rs]+key[x];
102         mul[x]=mul[ls]*key[x]*mul[rs]%mod;
103         */
104         
105 //inline void splay(int x,int goal){//double rotate
106 //    for(int f;(f=fa[x])!=goal;rotate(x))
107 //        if(fa[f]!=goal)
108 //            rotate((get(x)==get(f))?f:x);
109 //    if(!goal)root=x;
110 //}定向双旋
View Code

 

posted @ 2019-06-27 10:20  Chiyo小朋友  阅读(133)  评论(0编辑  收藏  举报