题意:给一个数,边之间有权值,然后两种操作,第一种:求任意两点的权值和,第二,修改树上两点的权值。
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\n" ,ans); 156 src = en; 157 } 158 } 159 } 160 return 0; 161 }
我还在坚持,我还未达到我所想,梦~~一直在