【模板】文艺平衡树(Splay)

[[Luogu3391]【模板】文艺平衡树(Splay)]


非指针版

 1 #define lo ch[o][0]
 2 #define ro ch[o][1]
 3 void maintain(int o){sz[o]=1+sz[lo]+sz[ro];}
 4 void pushdown(int o){if(!laz[o]) return ; swap(lo, ro); if(lo) laz[lo]^=1; if(ro) laz[ro]^=1; laz[o]=0;}
 5 void ins(int &o, int x){
 6     if(!o){o=++cnt; val[o]=x; sz[o]=1; return ;}
 7     if(x < val[o]) ins(ch[o][0], x); else ins(ch[o][1], x); maintain(o);
 8 }
 9 void rot(int &o, int d){
10     pushdown(o); int p=ch[o][d^1]; pushdown(p);
11     ch[o][d^1]=ch[p][d]; ch[p][d]=o; maintain(o); maintain(p); o=p; 
12 }
13 int scmp(int o, int &k){if(sz[lo]+1 == k) return -1; if(sz[lo]+1 > k) return 0; k-=sz[lo]+1; return 1;}
14 void splay(int &o, int k){
15     if(!o) return ; pushdown(o); int d=scmp(o, k); if(d == -1) return ;
16     int p=ch[o][d]; if(!p) return ; pushdown(p);
17     int k2=k, d2=scmp(p, k2); if(d2 == -1) {rot(o, d^1); return ;}
18     splay(ch[p][d2], k2); if(d == d2) rot(o, d^1); else rot(ch[o][d], d); rot(o, d^1);
19 }
20 void rev(int l, int r){
21     splay(rt, r+2); splay(ch[rt][0], l);
22     if(ch[ch[rt][0]][1]) laz[ch[ch[rt][0]][1]]^=1;
23 }
24 
25 void print(int o){
26     pushdown(o);
27     if(ch[o][0]) print(ch[o][0]);
28     if(val[o] != n+1 && val[o]) printf("%d ", val[o]);
29     if(ch[o][1]) print(ch[o][1]);
30 }
31 
32 void solve(){
33     n=read(), m=read();
34     for(int i=0; i <= n+1; i++) ins(rt, i), splay(rt, i+1); 
35     for(int i=1; i <= m; i++){int l=read(), r=read(); rev(l, r);}
36     print(rt);
37 }

 

指针版(以前不压行的代码看着好长好啰嗦啊)

 1 struct node
 2 {
 3     node* ch[2];
 4     int laz,s,v;
 5     node(int v):v(v){s=1;ch[0]=ch[1]=NULL;laz=0;}
 6     int cmp(int &k)
 7     {
 8         int ss=(ch[0] == NULL ? 0 : ch[0]->s);
 9         if(k == ss+1) return -1;
10         if(k > ss) {k-=ss+1;return 1;}
11         return 0;
12     }
13     void maintain(){ 
14         s=1; 
15         if(ch[0]!=NULL) s+=ch[0]->s; 
16         if(ch[1]!=NULL) s+=ch[1]->s; 
17     }
18     void pushdown()
19     {
20         if(laz)
21         {
22             swap(ch[0],ch[1]);
23             if(ch[0]!=NULL) ch[0]->laz^=1;
24             if(ch[1]!=NULL) ch[1]->laz^=1;
25             laz=0;
26         }
27     }
28 };
29 node* rt=NULL;
30 
31 void rot(node* &o,int d)
32 {
33     o->pushdown();node* k=o->ch[d^1];
34     k->pushdown();o->ch[d^1]=k->ch[d];k->ch[d]=o;
35     o->maintain();k->maintain();o=k;
36 }
37 
38 void splay(node* &o,int k)
39 {
40     if(o == NULL) return ;
41     o->pushdown();
42     int d=o->cmp(k);
43     if(d != -1)
44     {
45 
46         node* p=o->ch[d];if(p == NULL) return ; 
47         p->pushdown();
48         int k2=k,d2=p->cmp(k2);
49         if(d2 != -1) 
50         { 
51             splay(p->ch[d2],k2); 
52             if(d == d2) rot(o,d^1); 
53             else rot(o->ch[d],d); 
54         }
55         rot(o,d^1);
56     }
57 }
58 
59 void ins(node* &o,int x)
60 {
61     if(o == NULL){o=new node(x);return ;}
62     int d=(x < o->v ? 0 : 1);ins(o->ch[d],x);
63     o->maintain();
64 }
65 
66 void rev(int l,int r)
67 {
68     splay(rt,r+2);
69     splay(rt->ch[0],l);
70     if(rt->ch[0]->ch[1] != NULL) 
71     rt->ch[0]->ch[1]->laz^=1;
72 }
73 
74 void print(node* o)
75 {
76     if(o==NULL) return ;
77     o->pushdown();
78     print(o->ch[0]);
79     if(o->v != n+1 && o->v)printf("%d ",o->v);
80     print(o->ch[1]);
81 }
82 void solve(){
83     n=read();m=read();
84     for(int i=1;i<=n+2;i++) {ins(rt,i-1);splay(rt,i);}
85     while(m--){int l=read(),r=read(); rev(l,r);}
86     print(rt);
87 }

 


posted @ 2017-11-27 20:11  zerolt  阅读(137)  评论(0编辑  收藏  举报