• 树链剖分


      1 #include <cstdio>
      2 #include <algorithm>
      3 #include <cstring>
      4 using namespace std;
      5  
      6 const int size = 30000;
      7 int num[size+10] , fa[size+10] , depth[size+10] , son[size+10] , top[size+10] , var[size+10] , pos[size+10];
      8 struct graph {
      9     int Next;
     10     int to;
     11 };
     12 graph edge[size*2+10];
     13 int head[size+10];
     14 struct seg_tree {
     15     int L , R;
     16     int maxvar , sum;
     17 };
     18 seg_tree tree[size<<2];
     19 int cnt , tot;
     20 int res_sum , res_max;
     21  
     22 void addEdge( int u , int v ) {
     23     edge[cnt].to = v;
     24     edge[cnt].Next = head[u];
     25     head[u] = cnt++;
     26 }
     27  
     28 void dfs( int u ) {
     29     num[u] = 1;
     30     for ( int i = head[u] ; ~i ; i = edge[i].Next ) {
     31         int v = edge[i].to;
     32         if ( v!=fa[u] ) {
     33             fa[v] = u;
     34             depth[v] = depth[u] + 1;
     35             dfs( v );
     36             num[u] += num[v];
     37             if ( son[u]==-1 || num[v] > num[son[u]] ) {
     38                 son[u] = v;
     39             }
     40         }
     41     }
     42 }
     43  
     44 void redfs( int u , int rt ) {
     45     top[u] = rt;
     46     pos[u] = ++ tot;
     47     if ( son[u]==-1 ) {
     48         return;
     49     }
     50     if ( ~son[u] ) {
     51         redfs( son[u] , rt );
     52     }
     53     for ( int i = head[u] ; ~i ; i = edge[i].Next ) {
     54         int v = edge[i].to;
     55         if ( v!=son[u] && v!=fa[u] ) {
     56             redfs( v , v );
     57         }
     58     }
     59 }
     60  
     61 void build( int rt , int L , int R ) {
     62     int M = ( L + R ) >> 1;
     63     tree[rt].L = L;
     64     tree[rt].R = R;
     65     if ( L==R ) {
     66         tree[rt].maxvar = tree[rt].sum = var[L];
     67         return;
     68     }
     69     build( rt<<1 , L , M );
     70     build( rt<<1|1 , M+1 , R );
     71     tree[rt].maxvar = max( tree[rt<<1].maxvar , tree[rt<<1|1].maxvar );
     72     tree[rt].sum = tree[rt<<1].sum + tree[rt<<1|1].sum;
     73 }
     74  
     75 void update( int rt , int p , int temp ) {
     76     int M = ( tree[rt].L + tree[rt].R ) >> 1;
     77     if ( tree[rt].L == tree[rt].R && tree[rt].L == p ) {
     78         tree[rt].maxvar = tree[rt].sum = temp;
     79         return;
     80     }
     81     if ( p<=M ) {
     82         update( rt<<1 , p , temp );
     83     } else {
     84         update( rt<<1|1 , p , temp );
     85     }
     86     tree[rt].maxvar = max( tree[rt<<1].maxvar , tree[rt<<1|1].maxvar );
     87     tree[rt].sum = tree[rt<<1].sum + tree[rt<<1|1].sum;
     88 }
     89  
     90 void query( int rt , int L , int R ) {
     91     int M = ( tree[rt].L + tree[rt].R ) >> 1;
     92     if ( L==tree[rt].L && tree[rt].R==R) {
     93         res_max = max( res_max , tree[rt].maxvar );
     94         res_sum += tree[rt].sum;
     95         return;
     96     }
     97     if ( R<=M ) {
     98         query( rt<<1 , L , R );
     99     } else if ( L>=M+1 ) {
    100         query( rt<<1|1 , L , R );
    101     } else {
    102         query( rt<<1 , L , M );
    103         query( rt<<1|1 , M+1 , R );
    104     }
    105 }
    106  
    107 void solve( int u , int v ) {
    108     res_sum = 0;
    109     res_max = -11111111;
    110     int tu = top[u];
    111     int tv = top[v];
    112     while ( tu!=tv ) {
    113         if ( depth[tu]<depth[tv] ) {
    114             swap(tu,tv);
    115             swap(u,v);
    116         }
    117         query( 1 , pos[tu] , pos[u] );
    118         u = fa[tu];
    119         tu = top[u];
    120     }
    121     if ( depth[u] > depth[v] ) {
    122         swap(u,v);
    123     }
    124     query( 1 , pos[u] , pos[v] );
    125 }
    126  
    127 int main( ) {
    128     int n;
    129     while ( ~scanf("%d",&n) ) {
    130         memset( head , -1 , sizeof(head) );
    131         cnt = 0;
    132         int u , v;
    133         for ( int i = 1 ; i<=n-1 ; ++i ) {
    134             scanf("%d %d",&u,&v);
    135             addEdge(u,v);
    136             addEdge(v,u);
    137         }
    138         memset( fa , -1 , sizeof(fa) );
    139         fa[1] = 1;
    140         memset( son , -1 , sizeof(son) );
    141         depth[1] = 1;
    142         dfs(1);
    143         tot = 0;
    144         redfs(1,1);
    145         for ( int i = 1 ; i<=n ; ++i ) {
    146             int x;
    147             scanf("%d",&x);
    148             var[ pos[i] ] = x;
    149         }
    150         build( 1 , 1 , tot );
    151         int q;
    152         scanf("%d",&q);
    153         while ( q-- ) {
    154             char str[10];
    155             scanf("%s %d %d",str,&u,&v);
    156             if ( str[0]=='C' ) {
    157                 update(1,pos[u],v);//结点u的值更新为v
    158             } else if ( str[3]=='X' ) {
    159                 solve(u,v);
    160                 printf("%d
    ",res_max);//查询路径从U->V的最大值
    161             } else {
    162                 solve(u,v);
    163                 printf("%d
    ",res_sum);//求路径从U->V的和值
    164             }
    165         }
    166     }
    167     return 0;
    168 }
    View Code
      1 #include <cstdio>
      2 #include <cstring>
      3 #include <algorithm>
      4 using namespace std;
      5 
      6 typedef __int64 lol;
      7 const int size = 50000;
      8 struct data {
      9     int Next;
     10     int to;
     11 };
     12 data edge[size*2+10];
     13 struct graph {
     14     int u , v;
     15     lol w;
     16     graph(){};
     17     graph( int x , int y , lol z ):u(x),v(y),w(z){};
     18 };
     19 graph node[size+10];
     20 struct seg_tree {
     21     int L , R;
     22     lol cost;
     23 };
     24 seg_tree tree[size<<2];
     25 int num[size+10] , fa[size+10] , depth[size+10] , son[size+10] , top[size+10] , pos[size+10];
     26 int head[size+10];
     27 lol var[size+10];
     28 int cnt;
     29 int tot;
     30 
     31 void addEdge( int u , int v ) {
     32     edge[cnt].to = v;
     33     edge[cnt].Next = head[u];
     34     head[u] = cnt ++;
     35 }
     36 
     37 void dfs( int u ) {
     38     num[u] = 1;
     39     for ( int i = head[u] ; ~i ; i = edge[i].Next ) {
     40         int v = edge[i].to;
     41         if ( v!=fa[u] ) {
     42             fa[v] = u;
     43             depth[v] = depth[u] + 1;
     44             dfs(v);
     45             num[u] += num[v];
     46             if ( son[u]==-1 || num[v] > num[son[u]] ) {
     47                 son[u] = v;
     48             }
     49         }
     50     }
     51 }
     52 
     53 void redfs( int u , int rt ) {
     54     top[u] = rt;
     55     pos[u] = ++ tot;
     56     if ( son[u] == -1 ) {
     57         return;
     58     }
     59     if ( ~son[u] ) {
     60         redfs( son[u] , rt );
     61     }
     62     for ( int i = head[u] ; ~i ; i = edge[i].Next ) {
     63         int v = edge[i].to;
     64         if ( v!=son[u] && v!=fa[u] ) {
     65             redfs( v , v );
     66         }
     67     }
     68 }
     69 
     70 void build( int rt , int L , int R ) {
     71     int M = ( L + R ) >> 1;
     72     tree[rt].L = L;
     73     tree[rt].R = R;
     74     if ( L==R ) {
     75         tree[rt].cost = var[L];
     76         return;
     77     }
     78     build( rt<<1 , L , M );
     79     build( rt<<1|1 , M+1 , R );
     80     tree[rt].cost = tree[rt<<1].cost + tree[rt<<1|1].cost;
     81 }
     82 
     83 void update( int rt , int p , lol val ) {
     84     int M = ( tree[rt].L + tree[rt].R ) >> 1;
     85     if ( tree[rt].L == tree[rt].R  ) {
     86         tree[rt].cost = val;
     87         return;
     88     }
     89     if ( p<=M ) {
     90         update( rt<<1 , p , val );
     91     } else {
     92         update( rt<<1|1 , p , val );
     93     }
     94     tree[rt].cost = tree[rt<<1].cost + tree[rt<<1|1].cost;
     95 }
     96 
     97 lol query( int rt , int L , int R ) {
     98     int M = ( tree[rt].L + tree[rt].R ) >> 1;
     99     if ( L<=tree[rt].L && tree[rt].R<=R) {
    100         return tree[rt].cost;
    101     }
    102     lol sum = 0;
    103     if ( L<=M ) {
    104         sum += query( rt<<1 , L , R );
    105     }
    106     if ( M<R ) {
    107         sum += query( rt<<1|1 , L , R );
    108     }
    109     return sum;
    110 }
    111 
    112 lol solve( int u , int v ) {
    113     int fu = top[u];
    114     int fv = top[v];
    115     lol sum = 0;
    116     while ( fu!=fv ) {
    117         if ( depth[fu] < depth[fv] ) {
    118             swap( fu , fv );
    119             swap( u , v );
    120         }
    121         sum += query( 1 , pos[fu] , pos[u] );
    122         u = fa[fu];
    123         fu = top[u];
    124     }    
    125     if ( u==v ) {
    126         return sum;
    127     }
    128     if ( depth[u] > depth[v] ) {
    129         swap( u , v );
    130     }
    131     sum += query( 1 , pos[son[u]] , pos[v] );
    132     return sum;
    133 }
    134 
    135 int main( ) {
    136     int n , m;
    137     while ( ~scanf("%d %d",&n,&m) ) {
    138         memset( head , -1 , sizeof(head) );
    139         cnt = 0;
    140         int u , v;
    141         lol w;
    142         for ( int i = 1 ; i<=n-1 ; ++i ) {
    143             scanf("%d %d %I64d",&u,&v,&w);
    144             addEdge( u , v );
    145             addEdge( v , u );
    146             node[i] = graph( u , v , w );
    147         }
    148         memset( son , -1 , sizeof(son) );
    149         memset( fa , -1 , sizeof(fa) );
    150         fa[1] = 1;
    151         depth[1] = 1;
    152         tot = 0;
    153         dfs( 1 );
    154         redfs( 1 , 1 );
    155         for ( int i = 1 ; i<=n-1 ; ++i ) {
    156             if ( depth[ node[i].u ] < depth[ node[i].v ] ) {
    157                 swap( node[i].u , node[i].v );
    158             }
    159             var[ pos[node[i].u] ] = node[i].w;
    160         }
    161         build( 1 , 2 , tot );
    162         while ( m-- ) {
    163             int type , x , y;
    164             scanf("%d %d %d",&type,&x,&y);
    165             if ( !type ) {
    166                 update( 1 , pos[node[x].u] , 1LL*y );   // 将第 x 条边的权值修改为 y
    167             } else {
    168                 printf("%I64d
    ",solve(x,y));
    169             }
    170         }
    171     }
    172     return 0;
    173 }
    View Code
  • 相关阅读:
    几种连接数据库的OLEDB驱动程序
    Javascript如何访问和处理系统文件
    如何自学Java 经典
    Android Studio 修改 包名
    Android Studio -导入项目 gradle处理
    Android Studio- 把项目提交到SVN中操作方法
    android studio 运行太慢了
    Java多线程 -sleep 用法详解
    Java -native 方法
    Java多线程 -yield用法
  • 原文地址:https://www.cnblogs.com/radical/p/4533128.html
Copyright © 2020-2023  润新知