HYSBZ - 1036 树的统计Count(树剖)
2015-10-13 23:33
302 查看
题目大意:中文题
解题思路:树剖裸题
解题思路:树剖裸题
#include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int N = 30010; const int M = 30010 << 2; const int INF = 0x3f3f3f3f; struct Edge{ int u, v, next; Edge() {} Edge(int u, int v, int next): u(u), v(v), next(next) {} }E[N * 2]; int n, q, tot, idx; int top , size , f , son , dep , id , head , val , weight , Sum[M], Max[M]; bool flag; void build(int u, int l, int r) { if (l == r) { Max[u] = Sum[u] = val[l]; return ; } int mid = (l + r) >> 1; build(2 * u, l, mid); build(2 * u + 1, mid + 1, r); Sum[u] = Sum[2 * u] + Sum[2 * u + 1]; Max[u] = max(Max[2 * u], Max[2 * u + 1]); } void dfs1(int u, int fa, int depth) { dep[u] = depth; size[u] = 1; son[u] = 0; f[u] = fa; for (int i = head[u]; ~i; i = E[i].next) { int v = E[i].v; if (v == fa) continue; dfs1(v, u, depth + 1); size[u] += size[v]; if (size[son[u]] < size[v]) son[u] = v; } } void dfs2(int u, int tp) { top[u] = tp; id[u] = ++idx; if (son[u]) dfs2(son[u], tp); for (int i = head[u]; ~i; i = E[i].next) { int v = E[i].v; if (v == f[u] || v == son[u]) continue; dfs2(v, v); } } void add(int u, int l, int r, int pos, int c) { if (l == r && l == pos) { Sum[u] = Max[u] = c; return ; } int mid = (l + r) >> 1; if (pos <= mid) add(2 * u, l, mid, pos, c); else add(2 * u + 1, mid + 1, r, pos, c); Sum[u] = Sum[2 * u] + Sum[2 * u + 1]; Max[u] = max(Max[2 * u], Max[2 * u + 1]); } int query(int u, int l, int r, int L, int R) { if (L <= l && r <= R) { if (flag) return Sum[u]; else return Max[u]; } int mid = (l + r) >> 1; int ans = -INF, tmp; if (flag) ans = 0; if (L <= mid) { tmp = query(2 * u, l, mid, L, R); if (flag) ans += tmp; else ans = max(ans, tmp); } if (R > mid) { tmp = query(2 * u + 1, mid + 1, r, L, R); if (flag) ans += tmp; else ans = max(ans, tmp); } return ans; } int gao(int u, int v) { int ans = -INF, tmp; if (flag) ans = 0; int tp1 = top[u], tp2 = top[v]; while (tp1 != tp2) { if (dep[tp1] < dep[tp2]) { swap(tp1, tp2); swap(u, v); } tmp = query(1, 1, idx, id[tp1], id[u]); if (flag) ans += tmp; else ans = max(ans, tmp); u = f[tp1]; tp1 = top[u]; } if (dep[u] > dep[v]) swap(u, v); tmp = query(1, 1, idx, id[u], id[v]); if (flag) ans += tmp; else ans = max(ans, tmp); return ans; } void solve() { char op[30]; int a, b; scanf("%d", &q); while (q--) { scanf("%s%d%d", op, &a, &b); if (op[0] == 'C') add(1, 1, idx, id[a], b); else { flag = false; if (op[1] == 'S') flag = true; printf("%d\n", gao(a, b)); } } } void AddEdge(int u, int v) { E[tot] = Edge(u, v, head[u]); head[u] = tot++; E[tot] = Edge(v, u, head[v]); head[v] = tot++; } void init() { memset(head, -1, sizeof(head)); tot = idx = 0; int u, v; for (int i = 1; i < n; i++) { scanf("%d%d", &u, &v); AddEdge(u, v); } dfs1(1, 0, 1); dfs2(1, 1); for (int i = 1; i <= n; i++) scanf("%d", &val[id[i]]); build(1, 1, idx); } int main() { while (scanf("%d", &n) != EOF) { init(); solve(); } return 0; }
相关文章推荐
- 安卓孵化之路(二)——基于监听的事件处理机制
- 案例:下大雪啦 漫天星星升级版
- 仿微信android app
- MySQL理解索引、添加索引的原则
- 设计模式的分类和六大设计原则
- 闲话字符编码(未完待续...)
- use of UINT64_C in libavutil/common.h
- Unity5 新功能解析--物理渲染与standard shader
- TCP带外数据读写
- POJ - 2763 Housewife Wind(树剖)
- 20.Oracle数据库SQL开发之 执行多表选择
- CPU调度
- 19.Oracle数据库SQL开发之 笛卡尔积
- Windows下解决端口占用问题
- spring boot实战(第十篇)Spring boot Bean加载源码分析
- c++课程感想5
- 18.Oracle数据库SQL开发之 使用表别名
- SSH和BootStrap-table分页
- Android内存优化之OOM
- java入门第四天作业之弹不出框的小球