splay伸展树模板

 

 普通版本:

  1 struct SplayTree
  2 {
  3 
  4     const static int maxn = 1e5 + 15;
  5 
  6     int tot,root,ch[maxn][2], key[maxn], val[maxn], sz[maxn], lz[maxn], fa[maxn];
  7 
  8     void init( int x, int ky, int v = 0, int par = 0 )
  9     {
 10         ch[x][0]=ch[x][1]=0, fa[x]= par, key[x] = ky, val[x] = v, sz[x] = 1;
 11     }
 12 
 13     void init()
 14     {
 15         init( 0, 0, 0 );
 16         sz[0] = 0;
 17         tot = root = 0 ;
 18     }
 19 
 20     inline void push_up(int x)
 21     {
 22         sz[x] = sz[ch[x][0]] + sz[ch[x][1]] + 1;
 23     }
 24 
 25     inline void push_down(int x)
 26     {
 27 
 28     }
 29 
 30     void rotate( int x, int d )
 31     {
 32         int y = fa[x];
 33         ch[y][d ^ 1] = ch[x][d];
 34         if ( ch[x][d]) fa[ch[x][d]] = y;
 35         fa[x] = fa[y];
 36         if (fa[y])
 37         {
 38             if (y == ch[fa[y]][d])  ch[fa[y]][d] = x;
 39             else  ch[fa[y]][d ^ 1] = x;
 40         }
 41         ch[x][d] = y, fa[y] = x;
 42         push_up( y ), push_up( x );
 43     }
 44 
 45     // Splay x to target's son
 46     void Splay( int x, int target )
 47     {
 48         while( fa[x] != target )
 49         {
 50             int y = fa[x];
 51             if( x == ch[y][0] )
 52             {
 53                 if( fa[y] != target && y == ch[fa[y]][0])
 54                     rotate( y, 1 );
 55                 rotate( x, 1 );
 56             }
 57             else
 58             {
 59                 if( fa[y] != target && y == ch[fa[y]][1])
 60                     rotate( y, 0 );
 61                 rotate( x, 0 );
 62             }
 63         }
 64         if( !target ) root = x;
 65     }
 66 
 67     void Insert( int & t, int ky, int v, int par = 0 )
 68     {
 69         if( t == 0 )
 70         {
 71             t = ++ tot;
 72             init( t, ky, v, par );
 73             Splay( tot, 0 );
 74         }
 75         else
 76         {
 77             int cur = t;
 78             if( v < key[t] ) Insert( ch[t][0], ky, v, cur );
 79             else Insert( ch[t][1], ky, v, cur );
 80             push_up( cur );
 81         }
 82     }
 83 
 84     // Return point
 85     int find( int t, int v )
 86     {
 87         if( t == 0 ) return 0;
 88         else if( key[t] == v )
 89         {
 90             Splay( t, 0 );
 91             return t;
 92         }
 93         else if( v < key[t] ) return find( ch[t][0], v );
 94         return find( ch[t][1], v );
 95     }
 96 
 97     // Delete Root
 98     void Delete()
 99     {
100         if( !ch[root][0] )
101         {
102             fa[ ch[root][1] ] = 0 ;
103             root = ch[root][1];
104         }
105         else
106         {
107             int cur = ch[root][0];
108             while( ch[cur][1] ) cur = ch[cur][1];
109             Splay( cur, root );
110             ch[cur][1] = ch[root][1];
111             root = cur, fa[cur] = 0, fa[ch[root][1]] = root;
112             push_up( root );
113         }
114     }
115 
116     int size()
117     {
118         return sz[root];
119     }
120     // 查第 k 小 , 必须保证合法
121     int kth( int x, int k )
122     {
123         if( k == sz[ch[x][0]] + 1 )
124         {
125             Splay( x, 0 );
126             return key[x];
127         }
128         else if( k <= sz[ch[x][0]] ) return kth( ch[x][0], k );
129         else return kth( ch[x][1], k - sz[ch[x][0]] - 1 );
130     }
131 
132     //找前驱
133     int pred( int t, int v )
134     {
135         if( t == 0 ) return v;
136         else
137         {
138             if( v <= key[t] ) return pred( ch[t][0], v );
139             else
140             {
141                 int ans =  pred( ch[t][1], v );
142                 if( ans == v )
143                 {
144                     ans = key[t];
145                     Splay( t, 0 );
146                 }
147                 return ans;
148             }
149         }
150     }
151 
152     /*int less( int t , int v ){
153         if( t == 0 ) return 0;
154         int rs = 0;
155         if( v <= key[t] ) rs = less( ch[t][0] , v );
156         else rs = sz[ch[t][0]] + 1 + less( ch[t][1] , v );
157         if( Tl ){
158             Splay( t , 0 );
159             Tl = 0;
160         }
161         return rs;
162     }*/
163 
164     //找后继
165     int succ( int t, int v )
166     {
167         if( t == 0 ) return v;
168         else
169         {
170             if( v >= key[t] ) return succ( ch[t][1], v );
171             else
172             {
173                 int ans =  succ( ch[t][0], v );
174                 if( ans == v )
175                 {
176                     ans = key[t];
177                     Splay( t, 0 );
178                 }
179                 return ans;
180             }
181         }
182     }
183 
184     void Preorder( int t )
185     {
186         if( !t ) return;
187         Preorder( ch[t][0] );
188         printf("%d ", key[t] );
189         Preorder( ch[t][1] );
190     }
191 
192 } sp;

区间更新版本-

  1 #include <bits/stdc++.h>
  2 
  3 using namespace std;
  4 
  5 #define lc ch[x][0]
  6 #define rc ch[x][1]
  7 #define pr fa[x]
  8 
  9 struct SplayTree
 10 {
 11 
 12     const static int maxn = 1e5 + 15;
 13 
 14     int tot,root,ch[maxn][2], key[maxn], val[maxn], sz[maxn], rev[maxn], fa[maxn];
 15 
 16     inline int wh(int x){ return ch[pr][1] == x;}
 17 
 18     inline void init( int x, int ky, int v = 0, int par = 0 )
 19     {
 20         lc=rc=0, fa[x]= par, key[x] = ky, val[x] = v, sz[x] = 1, rev[x] = 0;
 21     }
 22 
 23     inline void init()
 24     {
 25         init( 0, 0, 0 );
 26         sz[0] = 0;
 27         tot = root = 0 ;
 28     }
 29 
 30     inline void push_up(int x)
 31     {
 32         sz[x] = sz[lc] + sz[rc] + 1;
 33     }
 34 
 35     inline void reverse(int x)
 36     {
 37         rev[x] ^= 1, swap( lc, rc);
 38     }
 39 
 40     inline void push_down(int x)
 41     {
 42         if(rev[x])
 43         {
 44             if(lc)  reverse(lc);
 45             if(rc)  reverse(rc);
 46             rev[x] = 0;
 47         }
 48     }
 49 
 50     void rotate( int x)
 51     {
 52         int f = fa[x], gf = fa[f], t1 = wh(x);
 53         if( gf ) ch[gf][wh(f)] = x;
 54         fa[x] = gf, ch[f][t1] = ch[x][1^t1], fa[ch[f][t1]] = f;
 55         ch[x][t1^1] = f, fa[f] = x;
 56         push_up( f ), push_up( x );
 57     }
 58 
 59     void splay( int x, int tar )
 60     {
 61         for(; pr != tar; rotate(x))
 62         if(fa[pr] != tar)
 63             rotate( wh(x) == wh(pr) ? pr: x);
 64         if( !tar ) root = x;
 65     }
 66 
 67     void insert( int ky, int v)
 68     {
 69         int x = root, ls = root;
 70         while(x)
 71         {
 72             push_down(x);
 73             sz[x] ++, ls = x;
 74             x = ch[x][ky > key[x]];
 75         }
 76         init( ++tot, ky, v, ls);
 77         ch[ls][ky > key[ls]] = tot;
 78         splay( tot, 0);
 79     }
 80 
 81     int find( int ky)
 82     {
 83         int x = root;
 84         while(x)
 85         {
 86             push_down(x);
 87             if(key[x] == ky) break;
 88             x = ch[x][ky > key[x]];
 89         }
 90         if(x)   splay(x,0);
 91         else x = -1;
 92         return x;
 93     }
 94 
 95     // Delete Root
 96     void Delete()
 97     {
 98         if( !ch[root][0] )
 99         {
100             fa[ ch[root][1] ] = 0 ;
101             root = ch[root][1];
102         }
103         else
104         {
105             int cur = ch[root][0];
106             while( ch[cur][1] ) cur = ch[cur][1];
107             splay( cur, root );
108             ch[cur][1] = ch[root][1];
109             root = cur, fa[cur] = 0, fa[ch[root][1]] = root;
110             push_up( root );
111         }
112     }
113 
114     int kth( int k)
115     {
116         int x = root;
117         if(sz[x] < k) return -1;
118         while(x)
119         {
120             push_down(x);
121             if(k == sz[lc] + 1) break;
122             if(k > sz[lc])
123                 k -= sz[lc] + 1, x = rc;
124             else
125                 x = lc;
126         }
127         if(x)   splay(x,0);
128         else x = -1;
129         return x;
130     }
131 
132     int pred( void)
133     {
134         int x = root;
135         if(!x || !lc)   return -1;
136         x = lc;
137         while(rc)    push_down(x), x = rc;
138         splay( x, 0);
139         return x;
140     }
141 
142     int succ( void)
143     {
144         int x = root;
145         if(!x || !rc) return -1;
146         x = rc;
147         while(lc)   push_down(x), x = lc;
148         splay( x, 0);
149         return x;
150     }
151 
152     void debug( int x )
153     {
154         if( !x ) return;
155         if(lc) debug( lc );
156         printf("%d ", key[x] );
157         if(rc) debug( rc );
158     }
159 
160 } sp;
161 
162 int main(void)
163 {
164     sp.init();
165     for(int i=1,x;i<=5;i++)
166         scanf("%d",&x),sp.insert(x,0);
167     sp.debug(sp.root);
168     return 0;
169 }

 启发式合并:

  1 /**************************************************************
  2     Problem: 2733
  3     User: weeping
  4     Language: C++
  5     Result: Accepted
  6     Time:4908 ms
  7     Memory:4436 kb
  8 ****************************************************************/
  9  
 10 #include <bits/stdc++.h>
 11  
 12 using namespace std;
 13  
 14 #define lc ch[x][0]
 15 #define rc ch[x][1]
 16  
 17 int n,m,q,f[100005];
 18  
 19 int fd(int x)
 20 {
 21     return f[x]==x?x:f[x]=fd(f[x]);
 22 }
 23  
 24 struct SplayTree
 25 {
 26  
 27     const static int maxn = 1e5 + 15;
 28  
 29     int tot,root,ch[maxn][2], key[maxn], val[maxn], sz[maxn], rev[maxn], fa[maxn];
 30  
 31     inline void init( int x, int ky, int v = 0, int par = 0 )
 32     {
 33         lc=rc=0, fa[x]= par, key[x] = ky, val[x] = v, sz[x] = 1, rev[x] = 0;
 34     }
 35  
 36     inline void init()
 37     {
 38         init( 0, 0, 0 );
 39         sz[0] = 0;
 40         tot = root = 0 ;
 41     }
 42  
 43     inline void push_up(int x)
 44     {
 45         sz[x] = sz[lc] + sz[rc] + 1;
 46     }
 47  
 48     inline void reverse(int x)
 49     {
 50         rev[x] ^= 1, swap( lc, rc);
 51     }
 52  
 53     inline void push_down(int x)
 54     {
 55         if(rev[x])
 56         {
 57             if(lc)  reverse(lc);
 58             if(rc)  reverse(rc);
 59             rev[x] = 0;
 60         }
 61     }
 62  
 63     void rotate( int x)
 64     {
 65         int f = fa[x], gf = fa[f];
 66         int t1 = (ch[f][1] == x), t2 = (ch[gf][1] == f);
 67         if( gf ) ch[gf][t2] = x;
 68         fa[x] = gf, ch[f][t1] = ch[x][1^t1], fa[ch[f][t1]] = f;
 69         ch[x][t1^1] = f, fa[f] = x;
 70         push_up( f ), push_up( x );
 71     }
 72  
 73     void splay( int x, int tar )
 74     {
 75         for(int f = fa[x], gf = fa[f]; f != tar; rotate(x), f = fa[x], gf = fa[f])
 76         if(gf != tar)
 77             rotate( ((ch[f][1] == x) == (ch[gf][1] == f) )? f: x);
 78         if( !tar ) root = x;
 79     }
 80  
 81     void insert( int ky, int v)
 82     {
 83         int x = root, ls = root;
 84         while(x)
 85         {
 86             push_down(x);
 87             sz[x] ++, ls = x;
 88             x = ch[x][ky > key[x]];
 89         }
 90         init( ++tot, ky, v, ls);
 91         ch[ls][ky > key[ls]] = tot;
 92         splay( tot, 0);
 93     }
 94  
 95     int find( int ky)
 96     {
 97         int x = root;
 98         while(x)
 99         {
100             push_down(x);
101             if(key[x] == ky) break;
102             x = ch[x][ky > key[x]];
103         }
104         if(x)   splay(x,0);
105         else x = -1;
106         return x;
107     }
108  
109     // Delete Root
110     void Delete()
111     {
112         if( !ch[root][0] )
113         {
114             fa[ ch[root][1] ] = 0 ;
115             root = ch[root][1];
116         }
117         else
118         {
119             int cur = ch[root][0];
120             while( ch[cur][1] ) cur = ch[cur][1];
121             splay( cur, root );
122             ch[cur][1] = ch[root][1];
123             root = cur, fa[cur] = 0, fa[ch[root][1]] = root;
124             push_up( root );
125         }
126     }
127  
128     int kth( int k)
129     {
130         int x = root;
131         if(sz[x] < k) return -1;
132         while(x)
133         {
134             push_down(x);
135             if(k == sz[lc] + 1) break;
136             if(k > sz[lc])
137                 k -= sz[lc] + 1, x = rc;
138             else
139                 x = lc;
140         }
141         if(x)   splay(x,0);
142         else x = -1;
143         return x;
144     }
145  
146     int pred( void)
147     {
148         int x = root;
149         if(!x || !lc)   return -1;
150         x = lc;
151         while(rc)    push_down(x), x = rc;
152         splay( x, 0);
153         return x;
154     }
155  
156     int succ( void)
157     {
158         int x = root;
159         if(!x || !rc) return -1;
160         x = rc;
161         while(lc)   push_down(x), x = lc;
162         splay( x, 0);
163         return x;
164     }
165  
166     void debug( int x )
167     {
168         if( !x ) return;
169         if(lc) debug( lc );
170         printf("%d ", key[x] );
171         if(rc) debug( rc );
172     }
173  
174     void qinsert(int y)
175     {
176         int x = root, ls = root, ky = key[y];
177         while(x)
178             ls = x, x = ch[x][ky > key[x]];
179         x = ls;
180         ch[x][ky > key[x]] = y,fa[y] = x, sz[y] = 1;
181         splay(y, 0);
182     }
183  
184     void qmerge(int x)
185     {
186         if(!x) return;
187         int tl = lc, tr = rc;
188         lc  = rc = 0;
189         qmerge(tl);
190         qinsert(x);
191         qmerge(tr);
192     }
193     void merge(int u,int v)
194     {
195         if(u == v) return ;
196         if(sz[u]>sz[v]) swap(u,v);
197         f[u] = v, splay( v, 0);
198         qmerge(u);
199     }
200 } sp;
201  
202  
203 int main(void)
204 {
205     scanf("%d%d",&n,&m);
206     for(int i=1,x;i<=n;i++)
207         scanf("%d",&x),f[i]=i,sp.key[i]=x,sp.sz[i]=1;
208     for(int i=1,u,v;i<=m;i++)
209         scanf("%d%d",&u,&v),sp.merge(fd(u),fd(v));
210     scanf("%d",&q);
211     char op[5];
212     for(int i=1,x,y;i<=q;i++)
213     {
214         scanf("%s%d%d",op,&x,&y);
215         if(op[0]=='B')
216             sp.merge(fd(x),fd(y));
217         else
218             sp.splay(x,0),printf("%d
",sp.kth(y));
219     }
220     return 0;
221 }
原文地址:https://www.cnblogs.com/weeping/p/7362353.html