Splay伸展树模板(Menci Style)
Posted lovely_lazy_tag
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Splay伸展树模板(Menci Style)相关的知识,希望对你有一定的参考价值。
很喜欢Menci写的Splay啊,好清爽,自己写了一遍~
想改为维护序列很简单,分裂,合并时记得补上哨兵就行~
1 #include<cstdio> 2 #define uint unsigned int 3 #define MAXN 1008611 4 #define MAX 0x7fffffff 5 using namespace std; 6 7 template<typename T,T INF> 8 struct Splay{ 9 enum Relation{ 10 L=0,R=1 11 }; 12 13 struct Node{ 14 Node *ch[2],*pa,**root; 15 T val; 16 uint size,cnt; 17 18 Node(const T &value,Node *parent,Node **root):pa(parent),root(root),val(value),cnt(1){ 19 ch[L]=ch[R]=NULL; 20 } 21 ~Node(){ 22 if(ch[L]) delete ch[L]; 23 if(ch[R]) delete ch[R]; 24 } 25 26 inline Relation relation(){return this==pa->ch[L]?L:R;} 27 28 inline void maintain(){size=(ch[L]?ch[L]->size:0)+(ch[R]?ch[R]->size:0)+cnt;} 29 30 inline void rot(){ 31 Relation r=relation(); 32 Node *old=pa; 33 34 if(old->pa) old->pa->ch[pa->relation()]=this; 35 pa=old->pa; 36 37 old->ch[r]=ch[r^1]; 38 if(ch[r^1]) ch[r^1]->pa=old; 39 40 ch[r^1]=old; 41 old->pa=this; 42 43 maintain(); 44 old->maintain(); 45 46 if(!pa) *root=this; 47 } 48 49 inline Node *splay(Node *tarpa=NULL){ 50 while(pa!=tarpa){ 51 if(pa->pa==tarpa) rot(); 52 else if(relation()==pa->relation()) pa->rot(),rot(); 53 else rot(),rot(); 54 } 55 return this; 56 } 57 58 inline Node *pred(){ 59 splay(); 60 Node *v=ch[L]; 61 while(v->ch[R]) v=v->ch[R]; 62 return v; 63 } 64 65 inline Node *succ(){ 66 splay(); 67 Node *v=ch[R]; 68 while(v->ch[L]) v=v->ch[L]; 69 return v; 70 } 71 72 inline uint rank(){ 73 return ch[L]?ch[L]->size:0; 74 } 75 }*root; 76 77 Splay():root(NULL){ 78 insert(INF),insert(-INF); 79 } 80 ~Splay(){ 81 delete root; 82 } 83 84 inline Node *find(const T &x){ 85 Node *v=root; 86 87 while(v&&v->val!=x){ 88 if(x<v->val) v=v->ch[L]; 89 else v=v->ch[R]; 90 } 91 92 return v?v->splay():NULL; 93 } 94 95 inline Node *insert(const T &x){ 96 Node *v=find(x); 97 98 if(v){ 99 ++v->cnt,v->maintain(); 100 return v; 101 } 102 103 Node **target=&root,*parent=NULL; 104 while(*target){ 105 parent=*target; 106 ++parent->size; 107 if(x<parent->val) target=&parent->ch[L]; 108 else target=&parent->ch[R]; 109 } 110 111 *target=new Node(x,parent,&root); 112 return (*target)->splay(); 113 } 114 115 inline void erase(Node *v){ 116 if(!v) return ; 117 118 if(v->cnt!=1){ 119 v->splay(); 120 --v->cnt; 121 v->maintain(); 122 return ; 123 } 124 125 Node *pred=v->pred(); 126 Node *succ=v->succ(); 127 pred->splay(); 128 succ->splay(pred); 129 130 delete succ->ch[L]; 131 succ->ch[L]=NULL; 132 133 succ->maintain(); 134 pred->maintain(); 135 } 136 137 inline void erase(const T &value){ 138 erase(find(value)); 139 } 140 141 inline uint rank(const T &value){ 142 Node *v=find(value); 143 if(v) return v->rank(); 144 else{ 145 v=insert(value); 146 uint ans=v->rank(); 147 erase(v); 148 return ans; 149 } 150 } 151 152 inline Node *select(uint k){ 153 ++k; 154 Node *v=root; 155 while(v->rank()+1>k||v->rank()+v->cnt<k){ 156 if(k<v->rank()+1) v=v->ch[L]; 157 else k-=v->rank()+v->cnt,v=v->ch[R]; 158 } 159 return v->splay(); 160 } 161 162 inline Node *select(uint l,uint r){ 163 Node *lbound=select(l-1); 164 Node *rbound=select(r+1); 165 166 lbound->splay(); 167 rbound->splay(lbound); 168 169 return rbound->ch[L]; 170 } 171 172 inline const T &pred(const T &value){ 173 Node *v=find(value); 174 if(v) return v->pred()->val; 175 v=insert(value); 176 const T &result=v->pred()->val; 177 erase(v); 178 return result; 179 } 180 181 inline const T &succ(const T &value){ 182 Node *v=find(value); 183 if(v) return v->succ()->val; 184 v=insert(value); 185 const T &result=v->succ()->val; 186 erase(v); 187 return result; 188 } 189 }; 190 191 int n; 192 Splay<int,MAX> splay; 193 194 void dfs(Splay<int,MAX>::Node *v, int depth) { 195 if (v->ch[Splay<int,MAX>::L]) dfs(v->ch[Splay<int,MAX>::L], depth + 1); 196 for (int i = 0; i < depth; i++) { 197 putchar(‘ ‘); 198 } 199 printf("%d\n", v->val); 200 if (v->ch[Splay<int,MAX>::R]) dfs(v->ch[Splay<int,MAX>::R], depth + 1); 201 } 202 203 void print() { 204 dfs(splay.root, 0); 205 puts("--------------------------------------------------"); 206 } 207 208 int main() { 209 scanf("%d", &n); 210 211 for (int i = 0; i < n; i++) { 212 int command, x; 213 scanf("%d %d", &command, &x); 214 if (command == 1) { 215 splay.insert(x); 216 } else if (command == 2) { 217 splay.erase(x); 218 } else if (command == 3) { 219 printf("%d\n", splay.rank(x)); 220 } else if (command == 4) { 221 printf("%d\n", splay.select(x)->val); 222 } else if (command == 5) { 223 printf("%d\n", splay.pred(x)); 224 } else if (command == 6) { 225 printf("%d\n", splay.succ(x)); 226 } 227 } 228 229 return 0; 230 }
以上是关于Splay伸展树模板(Menci Style)的主要内容,如果未能解决你的问题,请参考以下文章