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)的主要内容,如果未能解决你的问题,请参考以下文章

splay伸展树模板

模板——伸展树 splay 实现快速分裂合并的序列

P3369 模板普通平衡树 题解(Splay)

伸展树(Splay Tree)

Splay伸展树学习笔记

伸展树(Splay)详解