BZOJ 3224 普通平衡树 平衡树的两种姿势:SBT,splay

Posted avancent

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了BZOJ 3224 普通平衡树 平衡树的两种姿势:SBT,splay相关的知识,希望对你有一定的参考价值。

题面:

3224: Tyvj 1728 普通平衡树

Time Limit: 10 Sec  Memory Limit: 128 MB
Submit: 14600  Solved: 6334
[Submit][Status][Discuss]

Description

您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作:
1. 插入x数
2. 删除x数(若有多个相同的数,因只删除一个)
3. 查询x数的排名(若有多个相同的数,因输出最小的排名)
4. 查询排名为x的数
5. 求x的前驱(前驱定义为小于x,且最大的数)
6. 求x的后继(后继定义为大于x,且最小的数)

Input

第一行为n,表示操作的个数,下面n行每行有两个数opt和x,opt表示操作的序号(1<=opt<=6)

Output

对于操作3,4,5,6每行输出一个数,表示对应答案

Sample Input

10
1 106465
4 1
1 317721
1 460929
1 644985
1 84185
1 89851
6 81968
1 492737
5 493598

Sample Output

106465
84185
492737

HINT

1.n的数据范围:n<=100000
2.每个数的数据范围:[-2e9,2e9]
 
技术分享
  1 #include<iostream>
  2 #include<stdio.h>
  3 using namespace std;
  4 #define lc(x) (tree[x].lc)
  5 #define rc(x) (tree[x].rc)
  6 #define maxn 1000001
  7 #define B(x) balance(x);balance(rc(x));balance(lc(x));return
  8 struct node
  9 {
 10     int lc,rc,size,w;
 11     node(){};
 12     node(int x)
 13     {
 14         w=x;lc=rc=0;size=1;
 15     }
 16 }tree[maxn];
 17 int cnt,root,n;
 18 void update(int id)
 19 {
 20     tree[id].size=tree[lc(id)].size+tree[rc(id)].size+1;
 21 }
 22 void r_(int &id)
 23 {
 24     int ix=lc(id);lc(id)=rc(ix);
 25     update(id);rc(ix)=id;
 26     update(ix);id=ix;
 27 }
 28 void l_(int &id)
 29 {
 30     int ix=rc(id);rc(id)=lc(ix);
 31     update(id);lc(ix)=id;
 32     update(ix);id=ix;
 33 }
 34 void balance(int &id)
 35 {
 36     if(tree[lc(lc(id))].size>tree[rc(id)].size)
 37     {
 38         r_(id);B(id);
 39     }
 40     if(tree[rc(rc(id))].size>tree[lc(id)].size)
 41     {
 42         l_(id);B(id);
 43     }
 44     if(tree[rc(lc(id))].size>tree[rc(id)].size)
 45     {
 46         l_(lc(id)),r_(id);B(id);
 47     }
 48     if(tree[lc(rc(id))].size>tree[lc(id)].size)
 49     {
 50         r_(rc(id)),l_(id);B(id);
 51     }
 52 }
 53 void insert(int &id,int w)
 54 {
 55     if(!id)
 56     {
 57         id=++cnt;
 58         tree[id]=node(w);
 59         return ;
 60     }
 61     if(w<tree[id].w)insert(lc(id),w);
 62     else insert(rc(id),w);
 63     update(id);balance(id);
 64 }
 65 void Delete(int &id,int w)
 66 {
 67     if(tree[id].w==w)
 68     {
 69         if(!lc(id)||!rc(id))
 70         {
 71             id=lc(id)+rc(id);
 72             return ;
 73         }
 74         r_(id);Delete(rc(id),w);
 75         update(id);balance(id);
 76         return ;
 77     }
 78     if(w<tree[id].w)Delete(lc(id),w);
 79     else Delete(rc(id),w);
 80     update(id);balance(id);
 81 }
 82 int RANK(int w)
 83 {
 84     int ans=0,t=root;
 85     while(t)
 86     {
 87         if(w>tree[t].w)  
 88             ans+=tree[lc(t)].size+1,t=rc(t);
 89         else
 90             t=lc(t);
 91     }
 92     return ans;
 93 }
 94 int kth(int k)
 95 {
 96     int t=root;
 97     while(t)
 98     {
 99         if(k==tree[lc(t)].size+1)return tree[t].w;
100         if(k<tree[lc(t)].size+1)t=lc(t);
101         else k-=tree[lc(t)].size+1,t=rc(t);
102     }
103     return 0;
104 }
105 int main()
106 {
107     int x,y;
108     scanf("%d",&n);
109     for(int i=1;i<=n;i++)
110     {
111         scanf("%d%d",&x,&y);
112         switch(x)
113         {
114             case 1:
115                 insert(root,y);
116                 break;
117             case 2:
118                 Delete(root,y);
119                 break;
120             case 3:
121                 printf("%d\n",RANK(y)+1);
122                 break;
123             case 4:
124                 printf("%d\n",kth(y));
125                 break;
126             case 5:
127                 printf("%d\n",kth(RANK(y)));
128                 break;
129             case 6:
130                 printf("%d\n",kth(RANK(y+1)+1));
131         }
132     }
133 }
SBT
技术分享
  1 #include<iostream>
  2 #include<cstdio>
  3 using namespace std;
  4 const int inf=2e9+9;
  5 class Splay
  6 {
  7     public:
  8         Splay()
  9         {
 10             root=NULL;    
 11             for(top=0;top<siz;++top)
 12                 stk[top]=tree+top;
 13         }    
 14         void insert(int w)
 15         {
 16             if(find(w)!=NULL)
 17                 ++root->count,update(root);
 18             else
 19                 if(root==NULL)
 20                     root=newnode(w,NULL);
 21                 else
 22                     splay(insert(root,w),NULL);
 23         }
 24         void erase(int w)
 25         {
 26             if(find(w)!=NULL)
 27                 erase(root,1);
 28         }
 29         int rank(int w)
 30         {
 31             if(find(w)!=NULL)
 32                 return size(root->son[0])+1;
 33             else
 34                 return 0;
 35         }
 36         int query(int k)
 37         {
 38             if(size(root)<k)
 39                 return 0;
 40             for(node *t=root;t;)
 41             {
 42                 if(k>size(t->son[0]))
 43                 {
 44                     k-=size(t->son[0]);
 45                     if(k>=1&&k<=t->count)
 46                         return t->w;
 47                     else
 48                     {    
 49                         k-=t->count;
 50                         t=t->son[1];    
 51                     }   
 52                 }
 53                 else
 54                     t=t->son[0];
 55             }
 56         }
 57         int pre(int w)
 58         {
 59             int sum=-inf;
 60             for(node *t=root;t;)
 61             {
 62                 if(t->w<w)
 63                     sum=max(t->w,sum);
 64                 t=t->son[w>t->w];
 65             }
 66             return sum;
 67         }
 68         int nex(int w)
 69         {
 70             int sum=inf;
 71             for(node *t=root;t;)
 72             {
 73                 if(t->w>w)
 74                     sum=min(t->w,sum);
 75                 t=t->son[w>=t->w];    
 76             }
 77             return sum;
 78         }
 79     private:
 80         struct node 
 81         {
 82             int count;
 83             int size;
 84             int w;
 85             node *fa;
 86             node *son[2];
 87         }*root;
 88         const static int siz=100005;
 89         node tree[siz],*stk[siz];
 90         int top;
 91         node *newnode(int w,node *f)
 92         {
 93             node *t=stk[--top];
 94             t->size=1;
 95             t->count=1;
 96             t->w=w;
 97             t->fa=f;
 98             t->son[0]=NULL;
 99             t->son[1]=NULL;
100             return t;
101         }
102         inline void freenode(node *t)
103         {
104             stk[top++]=t;
105         }
106         inline bool Son(node *t,node *f)
107         {
108             return f==NULL?0:f->son[1]==t;
109         }
110         inline int size(node *t)
111         {
112             return t==NULL?0:t->size;    
113         }
114         void update(node *t)
115         {
116             if(t!=NULL)
117             {
118                 t->size=t->count;
119                 t->size+=size(t->son[0]);
120                 t->size+=size(t->son[1]);
121             }
122         }
123         void connect(node *f,node *t,bool flag)
124         {
125             if(f==NULL)
126                 root=t;
127             else
128                 f->son[flag]=t;
129             if(t!=NULL)
130                 t->fa=f;
131         }
132         void rotate(node *t)
133         {
134             node *f=t->fa;
135             node *g=f->fa;
136             bool a=Son(t,f),b=!a;
137             connect(f,t->son[b],a);
138             connect(g,t,Son(f,g));
139             connect(t,f,b);
140             update(f);
141             update(t);
142         }
143         void splay(node *t,node *p)
144         {
145             if(t!=NULL)
146             {
147                 node *f,*g;
148                 while(t->fa!=p)
149                 {
150                     f=t->fa;
151                     g=f->fa;
152                     if(g==p)
153                         rotate(t);
154                     else    
155                     {
156                         if(Son(f,g)^Son(t,f))
157                             rotate(t),rotate(t);
158                         else    
159                             rotate(f),rotate(t);
160                     }
161                 }
162             }
163         }      
164         node *find(int w)
165         {
166             node *t=root;
167             while(t!=NULL&&t->w!=w)
168                 t=t->son[w>=t->w];
169             return splay(t,NULL),t;
170         }
171         node *insert(node *t,int w)
172         {
173             node *s=t->son[w>=t->w];
174             if(s==NULL)
175                 s=t->son[w>=t->w]=newnode(w,t);
176             else
177                 s=insert(s,w);
178             return update(t),s;
179         }
180         void erase(node *t)
181         {
182             if(t->son[0]==NULL)
183             {
184                 connect(NULL,t->son[1],0);
185                 update(root);    
186             }
187             else
188                 if(t->son[1]==NULL)
189                 {
190                     connect(NULL,t->son[0],0);
191                     update(root);    
192                 }  
193                 else    
194                 {
195                     node *s=t->son[0];
196                     while(s->son[1]!=NULL)
197                         s=s->son[1];
198                     splay(s,t);
199                     connect(NULL,s,0);
200                     connect(s,t->son[1],1);
201                     update(root);
202                 }
203             freenode(t);
204         }
205         void erase(node *t,int k)
206         {
207             t->count-=k;
208             if(t->count<=0)
209                 erase(t);
210             else    
211                 update(t);
212         }
213 }S;
214 int n;
215 int main()
216 {
217     int x,y;
218     scanf("%d",&n);
219     for(int i=1;i<=n;i++)
220     {
221         scanf("%d%d",&x,&y);
222         switch(x)
223         {
224             case 1: 
225                 S.insert(y);
226                 break;
227             case 2:
228                 S.erase(y);
229                 break;
230             case 3:
231                 printf("%d\n",S.rank(y));
232                 break;
233             case 4:
234                 printf("%d\n",S.query(y));
235                 break;
236             case 5:
237                 printf("%d\n",S.pre(y));
238                 break;
239             case 6:
240                 printf("%d\n",S.nex(y));
241                 break;
242         }    
243     }
244 }
Splay

 























以上是关于BZOJ 3224 普通平衡树 平衡树的两种姿势:SBT,splay的主要内容,如果未能解决你的问题,请参考以下文章

BZOJ3224_普通平衡树_KEY

bzoj 3224: Tyvj 1728 普通平衡树 && loj 104 普通平衡树 (splay树)

BZOJ 3224 普通平衡树

[bzoj3224]普通平衡树

[代码] bzoj 3224 普通平衡树(无旋treap)

bzoj3224: Tyvj 1728 普通平衡树