• 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
    " );
    123             else {
    124                 printf( "yes
    " );
    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
    ", L::qu_sum(u,v) );
    134             else
    135                 printf( "impossible
    " );
    136         }
    137     }
    138 }
    View Code
  • 相关阅读:
    Linux 文件查询
    Linux 文件与目录的权限
    Linux查看文件内容
    Linux文件与目录管理
    Linux的文件权限
    java 源码编译
    jvm 字节码执行 (二)动态类型支持与基于栈的字节码解释执行
    jvm 字节码执行 (一)方法调用
    玩转mongodb(七):索引,速度的引领(全文索引、地理空间索引)
    玩转mongodb(六):索引,速度的引领(普通索引篇)
  • 原文地址:https://www.cnblogs.com/idy002/p/4291483.html
Copyright © 2020-2023  润新知