1. 程式人生 > >P3369 【模板】普通平衡樹(Splay)

P3369 【模板】普通平衡樹(Splay)

lse 分享 can 復數 += www clas esp 重復數

題目鏈接:https://www.luogu.org/problemnew/show/P3369

修改了一下之前的模板,支持重復數值的存儲

技術分享圖片
  1 #include<bits/stdc++.h>
  2 using namespace std;
  3 struct node
  4 {
  5     int val;
  6     node *father;
  7     node *son[2];
  8     int cnt;
  9     int siz;
 10 } tree[100005],*root;
 11 inline void init(node *p,int
val=0) 12 { 13 p->father=NULL; 14 p->son[0]=p->son[1]=NULL; 15 p->val=val; 16 p->siz=1; 17 p->cnt=1; 18 } 19 inline int siz(node *t) 20 { 21 return t == NULL ? 0 : t->siz; 22 } 23 inline void update(node *t)//rotate與erase操作時需更新 24 {
25 t->siz = t->cnt; 26 t->siz += siz(t->son[0]); 27 t->siz += siz(t->son[1]); 28 } 29 inline bool son(node *f, node *s) 30 { 31 return f->son[1] == s; 32 } 33 inline void rotate(node *t) 34 { 35 node *f = t->father; 36 node *g = f->father;
37 bool a = son(f, t), b = !a; 38 f->son[a] = t->son[b]; 39 if (t->son[b] != NULL) 40 t->son[b]->father = f; 41 t->son[b] = f; 42 f->father = t; 43 t->father = g; 44 if (g != NULL) 45 g->son[son(g, f)] = t; 46 else 47 root = t; 48 update(t); 49 update(f); 50 } 51 inline void splay(node *t, node *p) 52 { 53 while (t->father != p) 54 { 55 node *f = t->father; 56 node *g = f->father; 57 if (g == p) 58 rotate(t); 59 else 60 { 61 if (son(g, f) ^ son(f, t)) 62 rotate(t), rotate(t); 63 else 64 rotate(f), rotate(t); 65 } 66 } 67 } 68 inline void insert(node* p) 69 { 70 if (root == NULL) 71 { 72 root = p; 73 return; 74 } 75 for(node* t=root; t; t = t->son[t->val < p->val]) 76 { 77 t->siz++; 78 if(t->val==p->val) 79 { 80 t->cnt++; 81 splay(t,NULL); 82 return; 83 } 84 if(t->son[t->val < p->val]==NULL) 85 { 86 t->son[t->val < p->val]=p; 87 p->father=t; 88 splay(p,NULL); 89 return; 90 } 91 } 92 } 93 inline void erase(node *t) 94 { 95 splay(t,NULL); 96 if (t->son[0] == NULL) 97 { 98 root = t->son[1]; 99 if (root != NULL) 100 root->father = NULL; 101 } 102 else 103 { 104 node *p = t->son[0]; 105 while (p->son[1] != NULL) 106 p = p->son[1]; 107 splay(p, t); 108 root = p; 109 root->father = NULL; 110 p->son[1] = t->son[1]; 111 if (p->son[1] != NULL) 112 p->son[1]->father = p; 113 update(p); 114 } 115 } 116 int n,m; 117 bool flag; 118 inline node* findx(int kth) 119 { 120 node* p=root; 121 while(1) 122 { 123 if(kth<=siz(p->son[0])) p=p->son[0]; 124 else 125 { 126 kth-=siz(p->son[0])+p->cnt; 127 if(kth<=0) return p; 128 p=p->son[1]; 129 } 130 } 131 } 132 inline node* findkth(int x) 133 { 134 node* p=root; 135 while(1) 136 { 137 if(p==NULL) return NULL; 138 if(p->val==x) return p; 139 p=p->son[p -> val < x]; 140 } 141 } 142 int main() 143 { 144 int m; 145 scanf("%d",&m); 146 int tot=0; 147 for(int i=1;i<=m;i++) 148 { 149 int op; 150 scanf("%d",&op); 151 if(op==1) 152 { 153 int x; 154 scanf("%d",&x); 155 init(&tree[++tot],x); 156 insert(&tree[tot]); 157 } 158 if(op==2) 159 { 160 int x; 161 scanf("%d",&x); 162 node* tmp=findkth(x); 163 if(tmp!=NULL) 164 { 165 tmp->cnt--; 166 if(!tmp->cnt) 167 erase(tmp); 168 else 169 splay(tmp,NULL); 170 } 171 } 172 if(op==3) 173 { 174 int x; 175 scanf("%d",&x); 176 node* tmp=findkth(x); 177 splay(tmp,NULL); 178 if(tmp->son[0]==NULL) 179 puts("1"); 180 else 181 printf("%d\n",tmp->son[0]->siz+1); 182 } 183 if(op==4) 184 { 185 int kth; 186 scanf("%d",&kth); 187 node *tmp=findx(kth); 188 if(tmp!=NULL) printf("%d\n",tmp->val); 189 } 190 if(op==5) 191 { 192 int x; 193 scanf("%d",&x); 194 node* p=root; 195 int tmp; 196 while(1) 197 { 198 if(p==NULL) break; 199 if(p->val>=x) 200 p=p->son[0]; 201 else 202 { 203 tmp=p->val; 204 p=p->son[1]; 205 } 206 } 207 printf("%d\n",tmp); 208 } 209 if(op==6) 210 { 211 int x; 212 scanf("%d",&x); 213 node* p=root; 214 int tmp; 215 while(1) 216 { 217 if(p==NULL) break; 218 if(p->val<=x) 219 p=p->son[1]; 220 else 221 { 222 tmp=p->val; 223 p=p->son[0]; 224 } 225 } 226 printf("%d\n",tmp); 227 } 228 } 229 }
View Code

P3369 【模板】普通平衡樹(Splay)