zoukankan      html  css  js  c++  java
  • 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 }
  • 相关阅读:
    LInux-crontab
    Linux权限-chmod1
    Tool_BurpSuite安装和简单使用
    python与redis交互(四)
    Flask_环境部署(十六)
    Nginx_配置文件nginx.conf配置详解
    Tool_linux环境安装python3和pip
    Nginx_全局命令设置
    Linux_无法解析域名
    VMware_克隆机器后主机Ping不同虚拟机,虚拟机能Ping通主机
  • 原文地址:https://www.cnblogs.com/weeping/p/7362353.html
Copyright © 2011-2022 走看看