FZU 2082 过路费 (树链剖分 修改单边权)
题目链接:http://acm.fzu.edu.cn/problem.php?pid=2082
树链剖分模版题,求和,修改单边权。
1 #include <iostream> 2 #include <cstdio> 3 #include <algorithm> 4 #include <cstring> 5 using namespace std; 6 typedef long long LL; 7 const int MAXN = 5e4 + 10; 8 struct EDGE { 9 int to , next; 10 LL cost; 11 }edge[MAXN << 1]; 12 int from[MAXN] , to[MAXN] , head[MAXN] , cnt , tot; 13 LL cost[MAXN] , val[MAXN] , dis[MAXN]; 14 int top[MAXN] , dep[MAXN] , size[MAXN] , son[MAXN] , par[MAXN] , id[MAXN]; 15 16 void init() { 17 memset(head , -1 , sizeof(head)); 18 cnt = tot = 0; 19 } 20 21 inline void add(int u , int v , LL cost) { 22 edge[tot].next = head[u]; 23 edge[tot].to = v; 24 edge[tot].cost = cost; 25 head[u] = tot++; 26 } 27 28 void dfs1(int u , int p , int d) { 29 dep[u] = d , par[u] = p , size[u] = 1 , son[u] = u; 30 for(int i = head[u] ; ~i ; i = edge[i].next) { 31 int v = edge[i].to; 32 if(v == p) 33 continue; 34 dfs1(v , u , d + 1); 35 if(size[v] > size[son[u]]) 36 son[u] = v; 37 size[u] += size[v]; 38 } 39 } 40 41 void dfs2(int u , int p , int t) { 42 top[u] = t , id[u] = ++cnt; 43 if(son[u] != u) 44 dfs2(son[u] , u , t); 45 for(int i = head[u] ; ~i ; i = edge[i].next) { 46 int v = edge[i].to; 47 if(v == son[u] || v == p) 48 continue; 49 dfs2(v , u , v); 50 } 51 } 52 53 struct SegTree { 54 int l , r; 55 LL sum; 56 }T[MAXN << 2]; 57 58 void build(int p , int l , int r) { 59 int mid = (l + r) >> 1; 60 T[p].l = l , T[p].r = r; 61 if(l == r) { 62 T[p].sum = val[l]; 63 return ; 64 } 65 build(p << 1 , l , mid); 66 build((p << 1)|1 , mid + 1 , r); 67 T[p].sum = T[p << 1].sum + T[(p << 1)|1].sum; 68 } 69 70 void updata(int p , int pos , LL num) { 71 int mid = (T[p].l + T[p].r) >> 1; 72 if(T[p].l == T[p].r && T[p].l == pos) { 73 T[p].sum = num; 74 return ; 75 } 76 if(pos <= mid) { 77 updata(p << 1 , pos , num); 78 } 79 else { 80 updata((p << 1)|1 , pos , num); 81 } 82 T[p].sum = T[p << 1].sum + T[(p << 1)|1].sum; 83 } 84 85 LL query(int p , int l , int r) { 86 int mid = (T[p].l + T[p].r) >> 1; 87 if(T[p].l == l && T[p].r == r) { 88 return T[p].sum; 89 } 90 if(r <= mid) { 91 return query(p << 1 , l , r); 92 } 93 else if(l > mid) { 94 return query((p << 1)|1 , l , r); 95 } 96 else { 97 return query(p << 1 , l , mid) + query((p << 1)|1 , mid + 1 , r); 98 } 99 } 100 101 LL Find(int u , int v) { 102 int fu = top[u] , fv = top[v]; 103 LL res = 0; 104 while(fu != fv) { 105 if(dep[fu] >= dep[fv]) { 106 res += query(1 , id[fu] , id[u]); 107 u = par[fu]; 108 fu = top[u]; 109 } 110 else { 111 res += query(1 , id[fv] , id[v]); 112 v = par[fv]; 113 fv = top[v]; 114 } 115 } 116 if(v == u) 117 return res; 118 else if(dep[u] > dep[v]) 119 return res + query(1 , id[son[v]] , id[u]); 120 else 121 return res + query(1 , id[son[u]] , id[v]); 122 } 123 124 int main() 125 { 126 int n, m , l , r , c; 127 while(~scanf("%d %d" , &n , &m)) { 128 init(); 129 for(int i = 1 ; i < n ; ++i) { 130 scanf("%d %d %lld" , from + i , to + i , cost + i); 131 add(from[i] , to[i] , cost[i]); 132 add(to[i] , from[i] , cost[i]); 133 } 134 dfs1(1 , 1 , 0); 135 dfs2(1 , 1 , 1); 136 //build(1 , 1 , cnt); 137 for(int i = 1 ; i < n ; ++i) { 138 if(dep[from[i]] < dep[to[i]]) 139 swap(from[i] , to[i]); 140 val[id[from[i]]] = cost[i]; 141 //updata(1 , id[from[i]] , cost[i]); 142 } 143 build(1 , 1 , cnt); 144 while(m--) { 145 scanf("%d %d %d" , &c , &l , &r); 146 if(c == 0) { 147 updata(1 , id[from[l]] , (LL)r); 148 } 149 else { 150 printf("%d\n" , Find(l , r)); 151 } 152 } 153 } 154 }