POJ 2763 树链剖分 线段树 Housewife Wind

单个边的权值修改以及询问路径上的权值之和。

数据量比较大,用vector存图会超时的。

  1 #include <iostream>
  2 #include <cstdio>
  3 #include <cstring>
  4 #include <algorithm>
  5 #include <vector>
  6 using namespace std;
  7 
  8 void scan(int& x)
  9 {
 10     x = 0;
 11     int ch = ' ';
 12     while(ch < '0' || ch > '9') ch = getchar();
 13     while(ch >= '0' && ch <= '9') { x = x * 10 + ch - '0'; ch = getchar(); }
 14 }
 15 
 16 int n, Q, s;
 17 
 18 const int maxn = 100000 + 10;
 19 int u[maxn], v[maxn], d[maxn];
 20 
 21 struct Edge
 22 {
 23     int v, nxt;
 24 };
 25 
 26 int cnt;
 27 int head[maxn];
 28 Edge edge[maxn * 2];
 29 
 30 void AddEdge(int u, int v)
 31 {
 32     edge[cnt].v = v;
 33     edge[cnt].nxt = head[u];
 34     head[u] = cnt++;
 35 }
 36 
 37 int tot;
 38 int L[maxn];
 39 int fa[maxn];
 40 int sz[maxn];
 41 int son[maxn];
 42 int id[maxn];
 43 int top[maxn];
 44 
 45 void dfs(int u)
 46 {
 47     sz[u] = 1; son[u] = 0;
 48     for(int i = head[u]; i != -1; i = edge[i].nxt)
 49     {
 50         int v = edge[i].v;
 51         if(v == fa[u]) continue;
 52         fa[v] = u;
 53         L[v] = L[u] + 1;
 54         dfs(v);
 55         sz[u] += sz[v];
 56         if(sz[v] > sz[son[u]]) son[u] = v;
 57     }
 58 }
 59 
 60 void dfs2(int u, int tp)
 61 {
 62     top[u] = tp;
 63     if(son[u]) { id[son[u]] = ++tot; dfs2(son[u], tp); }
 64     for(int i = head[u]; i != -1; i = edge[i].nxt)
 65     {
 66         int v = edge[i].v;
 67         if(v == fa[u] || v == son[u]) continue;
 68         id[v] = ++tot;
 69         dfs2(v, v);
 70     }
 71 }
 72 
 73 int sum[maxn << 2];
 74 
 75 void update(int o, int L, int R, int p, int v)
 76 {
 77     if(L == R) { sum[o] = v; return ; }
 78     int M = (L + R) / 2;
 79     if(p <= M) update(o<<1, L, M, p, v);
 80     else update(o<<1|1, M+1, R, p, v);
 81     sum[o] = sum[o<<1] + sum[o<<1|1];
 82 }
 83 
 84 int query(int o, int L, int R, int qL, int qR)
 85 {
 86     if(qR < L || qL > R) return 0;
 87     if(qL <= L && R <= qR) return sum[o];
 88     int ans = 0;
 89     int M = (L + R) / 2;
 90     ans += query(o<<1, L, M, qL, qR);
 91     ans += query(o<<1|1, M+1, R, qL, qR);
 92     return ans;
 93 }
 94 
 95 int Query(int u, int v)
 96 {
 97     int ans = 0;
 98     int t1 = top[u], t2 = top[v];
 99     while(t1 != t2)
100     {
101         if(L[t1] < L[t2]) { swap(u, v); swap(t1, t2); }
102         ans += query(1, 1, tot, id[t1], id[u]);
103         u = fa[t1]; t1 = top[u];
104     }
105     if(u == v) return ans;
106     if(L[u] < L[v]) swap(u, v);
107     ans += query(1, 1, tot, id[son[v]], id[u]);
108     return ans;
109 }
110 
111 int main()
112 {
113     while(scanf("%d%d%d", &n, &Q, &s) == 3)
114     {
115         memset(head, -1, sizeof(head));
116         cnt = 0;
117         for(int i = 1; i < n; i++)
118         {
119             scan(u[i]); scan(v[i]); scan(d[i]);
120             AddEdge(u[i], v[i]);
121             AddEdge(v[i], u[i]);
122         }
123 
124         L[1] = fa[1] = 0;
125         dfs(1);
126         tot = 0;
127         dfs2(1, 1);
128 
129         memset(sum, 0, sizeof(sum));
130         for(int i = 1; i < n; i++)
131         {
132             if(L[u[i]] < L[v[i]]) swap(u[i], v[i]);
133             update(1, 1, tot, id[u[i]], d[i]);
134         }
135 
136         int op, x, y;
137         while(Q--)
138         {
139             scan(op);
140             if(op == 0)
141             {
142                 scan(x);
143                 printf("%d\n", Query(s, x));
144                 s = x;
145             }
146             else
147             {
148                 scan(x); scan(y);
149                 update(1, 1, tot, id[u[x]], y);
150             }
151         }
152     }
153 
154     return 0;
155 }
代码君

 

posted @ 2015-08-06 15:10  AOQNRMGYXLMV  阅读(187)  评论(0编辑  收藏  举报