splay伸展树模板

Posted weeping

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了splay伸展树模板相关的知识,希望对你有一定的参考价值。

  1 struct SplayTree
  2 {
  3 
  4     const static int maxn = 1e5 + 15;
  5 
  6     int tot,root,ch[maxn][2], key[maxn], sz[maxn], lz[maxn], fa[maxn];
  7 
  8     void init( int x, int v = 0, int par = 0 )
  9     {
 10         ch[x][0]=ch[x][1]=0, fa[x]= par, key[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 v, int par = 0 )
 68     {
 69         if( t == 0 )
 70         {
 71             t = ++ tot;
 72             init( t, v, par );
 73             Splay( tot, 0 );
 74         }
 75         else
 76         {
 77             int cur = t;
 78             if( v < key[t] ) Insert( ch[t][0], v, cur );
 79             else Insert( ch[t][1], 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 } splay;

 

以上是关于splay伸展树模板的主要内容,如果未能解决你的问题,请参考以下文章

Splay伸展树模板(Menci Style)

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

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

伸展树(Splay Tree)

Splay伸展树学习笔记

伸展树(Splay)详解