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 }

 

posted @ 2016-05-22 19:48  Recoder  阅读(205)  评论(0编辑  收藏  举报