首页 > 代码库 > 【BZOJ 1036】【ZJOI 2008】树的统计
【BZOJ 1036】【ZJOI 2008】树的统计
<style></style>
此题为树链剖分的裸题。 代码如下,使用常用的轻重链剖分。
/************************************************************** Problem: 1036 User: Evensgn Language: C++ Result: Accepted Time:2468 ms Memory:5772 kb****************************************************************/#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>#include <cmath>#include <cstdlib>using namespace std;const int MaxE = 30000 + 5, MaxN = 30000 + 5;int n, q, topH, W[MaxN], f[MaxN], dep[MaxN], top[MaxN], son[MaxN], h[MaxN], size[MaxN], A[MaxN];int Ans;struct treeNode{ int sum, max;} T[MaxN * 4];struct edge { int u, v; edge *next;} E[MaxE * 2], *P = E, *point[MaxN];inline void addedge(int x, int y){ ++P; P -> u = x; P -> v = y; P -> next = point[x]; point[x] = P;}int DFS_1(int now, int depth, int fa){ f[now] = fa; dep[now] = depth; int sonSize, maxSonSize = 0; size[now] = 1; for (edge *j = point[now]; j; j = j -> next) { if (j -> v != f[now]) { sonSize = DFS_1(j -> v, depth + 1, now); size[now] += sonSize; if (maxSonSize < sonSize) { son[now] = j -> v; maxSonSize = sonSize; } } } return size[now];}void DFS_2(int now){ if (now != son[f[now]]) top[now] = now; else top[now] = top[f[now]]; h[now] = ++topH; A[h[now]] = W[now]; if (son[now]) DFS_2(son[now]); for (edge *j = point[now]; j; j = j -> next) if (j -> v != son[now] && j -> v != f[now]) DFS_2(j -> v);}int max(int a, int b){ if (a > b) return a; return b;}void update(int x){ T[x].sum = T[x * 2].sum + T[x * 2 + 1].sum; T[x].max = max(T[x * 2].max, T[x * 2 + 1].max);}void buildTree(int x, int s, int t){ if (s == t) { T[x].sum = A[s]; T[x].max = A[s]; return; } int m = (s + t) >> 1; buildTree(x * 2, s, m); buildTree(x * 2 + 1, m + 1, t); update(x);}void change(int x, int s, int t, int loc, int num){ if (s == t) { T[x].sum = num; T[x].max = num; return; } int m = (s + t) >> 1; if (loc <= m) change(x * 2, s, m, loc, num); else change(x * 2 + 1, m + 1, t, loc, num); update(x);}int getMax(int x, int s, int t, int l, int r){ if (l <= s && r >= t) return T[x].max; int m = (s + t) >> 1, ans = -999999999; if (l <= m) ans = max(ans, getMax(x * 2, s, m, l, r)); if (r >= m + 1) ans = max(ans, getMax(x * 2 + 1, m + 1, t, l, r)); return ans;}int getSum(int x, int s, int t, int l, int r){ if (l <= s && r >= t) return T[x].sum; int m = (s + t) >> 1, ans = 0; if (l <= m) ans += getSum(x * 2, s, m, l, r); if (r >= m + 1) ans += getSum(x * 2 + 1, m + 1, t, l, r); return ans;}void queryMax(int s, int t){ int f1, f2; f1 = 0; f2 = 1; while (f1 != f2) { f1 = top[s]; f2 = top[t]; if (f1 != f2) { if (dep[f1] >= dep[f2]) { Ans = max(Ans, getMax(1, 1, n, h[f1], h[s])); s = f[f1]; } else { Ans = max(Ans, getMax(1, 1, n, h[f2], h[t])); t = f[f2]; } } else { if (s == t) Ans = max(Ans, getMax(1, 1, n, h[s], h[s])); else { if (dep[s] >= dep[t]) Ans = max(Ans, getMax(1, 1, n, h[t], h[s])); else Ans = max(Ans, getMax(1, 1, n, h[s], h[t])); } } }}void querySum(int s, int t){ int f1, f2; f1 = 0; f2 = 1; while (f1 != f2) { f1 = top[s]; f2 = top[t]; if (f1 != f2) { if (dep[f1] >= dep[f2]) { Ans += getSum(1, 1, n, h[f1], h[s]); s = f[f1]; } else { Ans += getSum(1, 1, n, h[f2], h[t]); t = f[f2]; } } else { if (s == t) Ans += getSum(1, 1, n, h[s], h[s]); else { if (dep[s] >= dep[t]) Ans += getSum(1, 1, n, h[t], h[s]); else Ans += getSum(1, 1, n, h[s], h[t]); } } }}int main(){// freopen("1.in", "r", stdin); scanf("%d", &n); int a, b; char flag[10]; for (int i = 1; i <= n - 1; i++) { scanf("%d%d", &a, &b); addedge(a, b); addedge(b, a); } for (int i = 1; i <= n; i++) scanf("%d", &W[i]); DFS_1(1, 1, 0); topH = 0; top[1] = 1; DFS_2(1); buildTree(1, 1, n); scanf("%d", &q); for (int i = 1; i <= q; i++) { scanf("%s%d%d", flag, &a, &b); if (!strcmp(flag, "QMAX")) { Ans = -999999999; queryMax(a, b); printf("%d\n", Ans); } else if (!strcmp(flag, "QSUM")) { Ans = 0; querySum(a, b); printf("%d\n", Ans); } else //Change one node { change(1, 1, n, h[a], b); } } return 0;}
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。