BZOJ 3224 普通平衡树 平衡树的两种姿势:SBT,splay
Posted avancent
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了BZOJ 3224 普通平衡树 平衡树的两种姿势:SBT,splay相关的知识,希望对你有一定的参考价值。
题面:
3224: Tyvj 1728 普通平衡树
Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 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
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
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 }
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 }
以上是关于BZOJ 3224 普通平衡树 平衡树的两种姿势:SBT,splay的主要内容,如果未能解决你的问题,请参考以下文章