Loading

BZOJ 1036:树的统计Count(树链剖分)

http://www.lydsy.com/JudgeOnline/problem.php?id=1036

题意:中文题意。

思路:也是普通的树链剖分。唯一注意的点是在change函数中

1     while(top[u] != top[v]) {
2         if(dep[top[u]] < dep[top[v]]) swap(u, v);
3         if(type == 1) ans = max(ans, query(1, 1, tim, tid[top[u]], tid[u], type));
4         else ans += query(1, 1, tim, tid[top[u]], tid[u], type);
5         u = fa[top[u]];
6     }

这里的dep比较的是节点的top节点的深度,而不是直接比较节点的深度。因为这里WA了好久。只能说还未完全理解透细节。

  1 #include <cstdio>
  2 #include <algorithm>
  3 #include <iostream>
  4 #include <cstring>
  5 #include <string>
  6 #include <cmath>
  7 #include <queue>
  8 #include <vector>
  9 using namespace std;
 10 #define N 30010
 11 #define INF 10000000000
 12 #define lson rt<<1, l, m
 13 #define rson rt<<1|1, m + 1, r
 14 
 15 struct node
 16 {
 17     int v, nxt, w;
 18 }edge[N*2];
 19 int top[N], tid[N], fa[N], son[N], siz[N], dep[N], rak[N], w[N], tim;
 20 int head[N], tot;
 21 struct T
 22 {
 23     long long sum;
 24     long long ma;
 25 }tree[N<<2];
 26 
 27 void init()
 28 {
 29     memset(head, -1, sizeof(head));
 30     memset(son, -1, sizeof(son));
 31     tot = tim = 0;
 32 }
 33 
 34 void add(int u, int v)
 35 {
 36     edge[tot].v = v; edge[tot].nxt = head[u]; head[u] = tot++;
 37 }
 38 
 39 void dfs1(int u, int f, int d)
 40 {
 41     siz[u] = 1;
 42     dep[u] = d;
 43     fa[u] = f;
 44     for(int i = head[u]; ~i; i = edge[i].nxt) {
 45         int v = edge[i].v;
 46         if(v == f) continue;
 47         dfs1(v, u, d + 1);
 48         siz[u] += siz[v];
 49         if(son[u] == -1 || siz[son[u]] < siz[v]) son[u] = v;
 50     }
 51 }
 52 
 53 void dfs2(int u, int tp)
 54 {
 55     top[u] = tp;
 56     tid[u] = ++tim;
 57     rak[tim] = u;
 58     if(son[u] == -1) return ;
 59     dfs2(son[u], tp);
 60     for(int i = head[u]; ~i; i = edge[i].nxt) {
 61         int v = edge[i].v;
 62         if(v != fa[u] && v != son[u]) dfs2(v, v);
 63     }
 64 }
 65 
 66 void pushup(int rt)
 67 {
 68     tree[rt].sum = tree[rt<<1].sum + tree[rt<<1|1].sum;
 69     tree[rt].ma = max(tree[rt<<1].ma, tree[rt<<1|1].ma);
 70 }
 71 
 72 void build(int rt, int l, int r)
 73 {
 74     tree[rt].sum = 0;
 75     tree[rt].ma = 0;
 76     if(l == r) {
 77         tree[rt].sum = w[rak[l]];
 78         tree[rt].ma = w[rak[l]];
 79         return ;
 80     }
 81     int m = (l + r) >> 1;
 82     build(lson); build(rson);
 83     pushup(rt);
 84 }
 85 
 86 void update(int rt, int l, int r, int id, int val)
 87 {
 88     if(l == r && l == id) {
 89         tree[rt].sum = val;
 90         tree[rt].ma = val;
 91         return ;
 92     }
 93     int m = (l + r) >> 1;
 94     if(id <= m) update(lson, id, val);
 95     else update(rson, id, val);
 96     pushup(rt);
 97 }
 98 
 99 long long query(int rt, int l, int r, int L, int R, int type)
100 {
101     long long ans = 0;
102     if(type == 1) ans = -INF;
103     if(L <= l && r <= R) {
104         if(type == 1) ans = max(ans, tree[rt].ma);
105         else ans += tree[rt].sum;
106         return ans;
107     }
108     int m = (l + r) >> 1;
109     if(L <= m) {
110         if(type == 1) ans = max(ans, query(lson, L, R, type));
111         else ans += query(lson, L, R, type);
112     }
113     if(m < R) {
114         if(type == 1) ans = max(ans, query(rson, L, R, type));
115         else ans += query(rson, L, R, type);
116     }
117     return ans;
118 }
119 
120 long long change(int u, int v, int type)
121 {
122     long long ans = 0;
123     if(type == 1) ans = -INF;
124     while(top[u] != top[v]) {
125         if(dep[top[u]] < dep[top[v]]) swap(u, v);
126         if(type == 1) ans = max(ans, query(1, 1, tim, tid[top[u]], tid[u], type));
127         else ans += query(1, 1, tim, tid[top[u]], tid[u], type);
128         u = fa[top[u]];
129     }
130     if(dep[u] > dep[v]) swap(u, v);
131     if(type == 1) ans = max(ans, query(1, 1, tim, tid[u], tid[v], type));
132     else ans += query(1, 1, tim, tid[u], tid[v], type);
133     return ans;
134 }
135 
136 int main()
137 {
138     int n, q;
139     scanf("%d", &n);
140     init();
141     for(int i = 1; i < n; i++) {
142         int u, v;
143         scanf("%d%d", &u, &v);
144         add(u, v); add(v, u);
145     }
146     for(int i = 1; i <= n; i++) scanf("%d", &w[i]);
147     dfs1(1, 1, 1);
148     dfs2(1, 1);
149     build(1, 1, tim);
150     // for(int i = 1; i <= n; i++) printf("tid[%d] : %d\n", i, tid[i]);
151     scanf("%d", &q);
152     while(q--) {
153         char s[10];
154         int a, b;
155         scanf("%s%d%d", s, &a, &b);
156         if(s[0] == 'C') {
157             update(1, 1, tim, tid[a], b);
158         } else {
159             int type = 1;
160             if(s[1] == 'S') type = 2;
161             printf("%lld\n", change(a, b, type));
162         }
163     }
164     return 0;
165 }

 

posted @ 2016-10-31 17:30  Shadowdsp  阅读(179)  评论(0编辑  收藏  举报