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\n",sp.kth(y)); 219 } 220 return 0; 221 }
作者:weeping
出处:www.cnblogs.com/weeping/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。