树链剖分

  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
原文地址:https://www.cnblogs.com/radical/p/4533128.html