spoj4155 OTOCI LCT

 

动态树,支持加边,修改点权,查询链的点权和。

 

  1 #include <cstdio>
  2 #include <iostream>
  3 #define maxn 30010
  4 using namespace std;
  5 
  6 namespace L {
  7     int pnt[maxn], pre[maxn], son[maxn][2], val[maxn], sum[maxn], rtg[maxn];
  8 
  9     void update( int nd ) {
 10         sum[nd] = val[nd] + sum[son[nd][0]] + sum[son[nd][1]];
 11     }
 12     void rotate( int nd, int d ) {
 13         int p = pre[nd];
 14         int s = son[nd][!d];
 15         int ss = son[s][d];
 16         son[nd][!d] = ss;
 17         son[s][d] = nd;
 18         if( p ) son[p][ nd==son[p][1] ] = s;
 19         else pnt[s] = pnt[nd];
 20         pre[nd] = s;
 21         pre[s] = p;
 22         pre[ss] = nd;
 23         update( nd );
 24         update( s );
 25     }
 26     void pushdown( int nd ) {
 27         if( rtg[nd] ) {
 28             int &ls = son[nd][0], &rs = son[nd][1];
 29             swap(ls,rs);
 30             rtg[ls] ^= 1;
 31             rtg[rs] ^= 1;
 32             rtg[nd] = 0;
 33         }
 34     }
 35     void big_push( int nd ) {
 36         if( pre[nd] ) big_push(pre[nd]);
 37         pushdown(nd);
 38     }
 39     void splay( int nd, int top=0 ) {
 40         big_push(nd);
 41         while( pre[nd]!=top ) {
 42             int p = pre[nd];
 43             int nl = nd==son[p][0];
 44             if( pre[p]==top ) {
 45                 rotate( p, nl );
 46             } else {
 47                 int pp = pre[p];
 48                 int pl = p==son[pp][0];
 49                 if( nl==pl ) {
 50                     rotate( pp, pl );
 51                     rotate( p, nl );
 52                 } else {
 53                     rotate( p, nl );
 54                     rotate( pp, pl );
 55                 }
 56             }
 57         }
 58     }
 59     void access( int nd ) {
 60         int u = nd;
 61         int v = 0;
 62         while( u ) {
 63             splay( u );
 64             int s = son[u][1];
 65             pre[s] = 0;
 66             pnt[s] = u;
 67             pre[v] = u;
 68             son[u][1] = v;
 69             update( u );
 70             v = u;
 71             u = pnt[u];
 72         }
 73         splay(nd);
 74     }
 75     void makeroot( int nd ) {
 76         access(nd);
 77         rtg[nd] ^= 1;
 78     }
 79     int findroot( int nd ) {
 80         while( pre[nd] ) nd=pre[nd];
 81         while( pnt[nd] ) {
 82             nd = pnt[nd];
 83             while( pre[nd] ) nd=pre[nd];
 84         }
 85         return nd;
 86     }
 87     bool sameroot( int u, int v ) {
 88         return findroot(u)==findroot(v);
 89     }
 90     void link( int u, int v ) {
 91         makeroot(u);
 92         makeroot(v);
 93         pnt[u] = v;
 94     }
 95     void up_val( int nd, int v ) {
 96         splay( nd );
 97         val[nd] = v;
 98         update( nd );
 99     }
100     int qu_sum( int u, int v ) {
101         makeroot(u);
102         access(v);
103         return val[v]+sum[son[v][0]];
104     }
105 };
106 
107 int n, q;
108 
109 int main() {
110     scanf( "%d", &n );
111     for( int i=1, w; i<=n; i++ ) {
112         scanf( "%d", &w );
113         L::up_val( i, w );
114     }
115     scanf( "%d", &q );
116     while( q-- ) {
117         char ch[100];
118         int u, v, w;
119         scanf( "%s", ch );
120         if( ch[0]=='b' ) {
121             scanf( "%d%d", &u, &v );
122             if( L::sameroot(u,v) ) printf( "no\n" );
123             else {
124                 printf( "yes\n" );
125                 L::link(u,v);
126             }
127         } else if( ch[0]=='p' ) {
128             scanf( "%d%d", &u, &w );
129             L::up_val( u, w );
130         } else {
131             scanf( "%d%d", &u, &v );
132             if( L::sameroot(u,v) ) 
133                 printf( "%d\n", L::qu_sum(u,v) );
134             else
135                 printf( "impossible\n" );
136         }
137     }
138 }
View Code

 

posted @ 2015-02-14 13:30  idy002  阅读(171)  评论(0编辑  收藏  举报