码迷,mamicode.com
首页 > 其他好文 > 详细

平衡树Splay模板

时间:2017-11-26 17:53:00      阅读:111      评论:0      收藏:0      [点我收藏+]

标签:efi   turn   splay   kth   nbsp   data   using   root   gets   

  1 //cooode by xiaolang
  2 #include<cstdio>
  3 #include<iostream>
  4 #define N 100010
  5 using namespace std;
  6 int fa[N],ch[N][2],siz[N],cnt[N],data[N],root,nn,n,tot;
  7 
  8 void pushup(int rt) {
  9     int l=ch[rt][0],r=ch[rt][1];
 10     siz[rt]=siz[l]+siz[r]+cnt[rt];
 11 }
 12 void rotate(int x,int &k) {
 13     int a=fa[x],b=fa[a],l,r;
 14     l= (ch[a][0]!=x);
 15     r= l^1;
 16     if(a==k) k=x;
 17     else
 18         ch[b][ch[b][1]==a]=x;
 19     fa[x]=b,fa[a]=x,fa[ch[x][r]]=a;
 20     ch[a][l]=ch[x][r],ch[x][r]=a;
 21     pushup(a);
 22 }
 23 void splay(int x,int &k) {
 24     int a,b;
 25     while(x!=k) {
 26         a=fa[x],b=fa[a];
 27         if(a!=k) {
 28             if((ch[a][0]==x)^(ch[b][0]==a))
 29                 rotate(x,k);
 30             else
 31                 rotate(a,k);
 32         }
 33         rotate(x,k);
 34         pushup(x);
 35     }
 36 }
 37 void ins(int &rt,int x) {
 38     if(rt==0) {
 39         rt=++nn;
 40         data[nn]=x;
 41         siz[nn]=cnt[nn]=1;
 42         return;
 43     }
 44     if(x==data[rt]) {
 45         cnt[rt]++;
 46         siz[rt]++;
 47         return;
 48     }
 49     if(x<data[rt]) {
 50         ins(ch[rt][0],x);
 51         fa[ch[rt][0]]=rt;
 52         pushup(rt);
 53     } else {
 54         ins(ch[rt][1],x);
 55         fa[ch[rt][1]]=rt;
 56         pushup(rt);
 57     }
 58 }
 59 int getmn(int rt) {
 60     while(ch[rt][0]) {
 61         rt=ch[rt][0];
 62     }
 63     if(!rt) return -1;
 64     return rt;
 65 }
 66 void del(int rt,int x) {
 67     if(data[rt]==x) {
 68         if(cnt[rt]>1) {
 69             cnt[rt]--;
 70             siz[rt]--;
 71         } else {
 72             splay(rt,root);
 73             int p=getmn(ch[rt][1]);
 74             if(p!=-1) {
 75                 splay(p,root);
 76                 fa[p]=0;
 77                 ch[p][0]=ch[rt][0];
 78                 fa[ch[rt][0]]=p;
 79                 pushup(p);
 80             } else {
 81                 root=ch[rt][0];
 82                 fa[ch[rt][0]]=0;
 83             }
 84         }
 85         return;
 86     }
 87     if(x<data[rt]) {
 88         del(ch[rt][0],x);
 89         pushup(rt);
 90     } else {
 91         del(ch[rt][1],x);
 92         pushup(rt);
 93     }
 94 }
 95 int getpre(int rt,int x) {
 96     int p=rt,ans;
 97     while(p) {
 98         if(x<=data[p]) {
 99             p=ch[p][0];
100         } else {
101             ans=p;
102             p=ch[p][1];
103         }
104     }
105     return ans;
106 }
107 int getsuc(int rt,int x) {
108     int p=rt,ans;
109     while(p) {
110         if(x>=data[p]) {
111             p=ch[p][1];
112         } else {
113             ans=p;
114             p=ch[p][0];
115         }
116     }
117     return ans;
118 }
119 int getk(int rt,int k) {
120     if(data[rt]==k) {
121         splay(rt,root);
122         if(ch[rt][0]==0) {
123             return 1;
124         } else {
125             return siz[ch[rt][0]]+1;
126         }
127     }
128     if(k<data[rt]) return getk(ch[rt][0],k);
129     else return getk(ch[rt][1],k);
130 }
131 int getkth(int rt,int k) {
132     int l=ch[rt][0];
133     if(siz[l]+1<=k&&k<=siz[l]+cnt[rt]) return data[rt];
134     if(k<siz[l]+1) return getkth(ch[rt][0],k);
135     if(siz[l]+cnt[rt]<k) return getkth(ch[rt][1],k-(siz[l]+cnt[rt]));
136 }
137 int main() {
138     scanf("%d",&n);
139     while(n--) {
140         int opt,x;
141         scanf("%d%d",&opt,&x);
142         if(opt==1) {
143             tot++;
144             ins(root,x);
145         }
146         if(opt==2) {
147             tot--;
148             del(root,x);
149         }
150         if(opt==3) {
151             printf("%d\n",getk(root,x));
152         }
153         if(opt==4) {
154             printf("%d\n",getkth(root,x));
155         }
156         if(opt==5) {
157             printf("%d\n",data[getpre(root,x)]);
158         }
159         if(opt==6) {
160             printf("%d\n",data[getsuc(root,x)]);
161         }
162     }
163     return 0;
164 }

 

平衡树Splay模板

标签:efi   turn   splay   kth   nbsp   data   using   root   gets   

原文地址:http://www.cnblogs.com/476974496xiaolang/p/7899305.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!