POJ 2763

 题意:给一个数,边之间有权值,然后两种操作,第一种:求任意两点的权值和,第二,修改树上两点的权值。

  1 #pragma comment(linker, "/STACK:1024000000,1024000000")
  2 #include <iostream>
  3 #include <cstdio>
  4 #include <cstring>
  5 #include <algorithm>
  6 using namespace std;
  7 #define N 100010
  8 #define ls o<<1
  9 #define rs o<<1|1
 10 #define define_m int m=(l+r)>>1
 11 #define ll long long
 12 
 13 int first[N] , k;
 14 
 15 struct Edge{
 16     int x , y , next , w;
 17     Edge(){}
 18     Edge(int x , int y , int next , int w):x(x),y(y),next(next),w(w){}
 19 }e[N<<1];
 20 
 21 void add_edge(int x , int y , int w)
 22 {
 23     e[k] = Edge(x , y , first[x] , w);
 24     first[x] = k++;
 25 }
 26 
 27 int sz[N] , fa[N] , son[N] , dep[N] , id[N] , top[N] , num;
 28 
 29 void dfs(int u , int f , int d)
 30 {
 31     sz[u] = 1 , fa[u] = f , dep[u] = d , son[u]=0;
 32     int maxn=0;
 33     for(int i=first[u] ; ~i ; i=e[i].next){
 34         int v = e[i].y;
 35         if(v == f) continue;
 36         dfs(v , u , d+1);
 37         sz[u] += sz[v];
 38         if(sz[v]>maxn) maxn=sz[v] , son[u]=v;
 39     }
 40 }
 41 
 42 void dfs1(int u , int f , int head)
 43 {
 44     top[u] = head;
 45     id[u] = ++num;
 46     if(son[u]){
 47         dfs1(son[u] , u , head);
 48     }
 49     for(int i=first[u] ; ~i ; i=e[i].next){
 50         int v = e[i].y;
 51         if(v == f || v == son[u]) continue;
 52         dfs1(v , u , v);
 53     }
 54 }
 55 
 56 int n , q , src , val[N] , sum[N<<2];
 57 
 58 void push_up(int o)
 59 {
 60     sum[o] = sum[ls]+sum[rs];
 61 }
 62 
 63 void build(int o , int l , int r)
 64 {
 65     if(l==r){
 66         sum[o] = val[l];
 67         return;
 68     }
 69     define_m;
 70     build(ls , l , m);
 71     build(rs , m+1 , r);
 72     push_up(o);
 73 }
 74 
 75 void update(int o , int l , int r , int p , int v)
 76 {
 77     if(l==r){
 78         sum[o] = v;
 79         return;
 80     }
 81     define_m;
 82     if(m>=p) update(ls , l , m , p , v);
 83     else update(rs , m+1 , r , p , v);
 84     push_up(o);
 85 }
 86 
 87 int query(int o , int l , int r , int s , int t)
 88 {
 89     if(l>=s && r<=t) return sum[o];
 90     define_m;
 91     int ans = 0;
 92     if(m>=s) ans+=query(ls , l , m , s , t);
 93     if(m<t) ans+=query(rs , m+1 , r , s , t);
 94     return ans;
 95 }
 96 
 97 int calPath(int u , int v)
 98 {
 99     int top1 = top[u] , top2 = top[v];
100     int ans = 0;
101     while(top1!=top2){
102         if(dep[top1]<dep[top2]){
103             swap(top1 , top2);
104             swap(u , v);
105         }
106         ans += query(1 , 2 , num , id[top1] , id[u]);
107       //  cout<<"range: "<<id[top1]<<" "<<id[u]<<" "<<ans<<endl;
108         u = fa[top1];
109         top1 = top[u];
110     }
111     if(u!=v){
112         if(dep[u]<dep[v]) swap(u , v);
113         ans += query(1 , 2 , num , id[son[v]] , id[u]);
114     }
115     return ans;
116 }
117 
118 int main()
119 {
120    // freopen("in.txt" , "r" , stdin);
121     while(~scanf("%d%d%d" , &n , &q , &src)){
122         memset(first , -1 , sizeof(first));
123         k = 0;
124         for(int i=0 ; i<n-1 ; i++){
125             int u , v , w;
126             scanf("%d%d%d" , &u , &v , &w);
127             add_edge(u , v , w);
128             add_edge(v , u , w);
129         }
130         num = 0;
131         dfs(1 , 0 , 1);
132         dfs1(1 , 0 , 1);
133       //  for(int i=1 ; i<=n ; i++) cout<<i<<" "<<son[i]<<" "<<id[i]<<endl;
134         for(int i=0 ; i<n-1 ; i++){
135             int j = i<<1;
136             if(fa[e[j].x] != e[j].y) val[id[e[j].y]] = e[j].w;
137             else val[id[e[j].x]] = e[j].w;
138         }
139         build(1 , 2 , num);
140         int en , op , t;
141         while(q--){
142             scanf("%d" , &op);
143             if(op){
144                 scanf("%d%d" , &t , &en);
145                 t--;
146                 int pos;
147                 if(fa[e[t*2].x] != e[t*2].y) pos = id[e[t*2].y];
148                 else pos = id[e[t*2].x];
149              //   cout<<"update: "<<pos<<endl;
150                 update(1 , 2 , num , pos , en);
151             }
152             else{
153                 scanf("%d" , &en);
154                 int ans = calPath(src , en);
155                 printf("%d
" ,ans);
156                 src = en;
157             }
158         }
159     }
160     return 0;
161 }
原文地址:https://www.cnblogs.com/CSU3901130321/p/4763956.html