【TOJ 3701.】A Pungent Problem【树链刨分】
来源:互联网 发布:南昌房地产交易数据 编辑:程序博客网 时间:2024/05/21 04:23
裸的树链刨分。可以当做入门题,或者splay也可以做
#include <cstdio>#include <cstring>#include <vector>#include <algorithm>using namespace std;#define N 30009#define lc (d<<1)#define rc (d<<1|1)#define mid (l+r>>1)#define inf 0x3f3f3f3fstruct Tr{ int mx, sum;}tr[N<<4];int n, sun[N], tid[N], top[N], val[N], dep[N], tot, tmp[N], fa[N];vector<int>V[N];int dfs(int u, int f) { int i, v, id = u, mx = 0, c = 1; fa[u] = f; for (i = 0;i < V[u].size();i++) { v = V[u][i]; if (v == f) continue; int tm = dfs(v, u); if (tm > mx) mx = tm, id = v; c += tm; } sun[u] = id; return c;}void dfs1(int u, int d, int Top) { int i, v; dep[u] = d, tid[u] = ++tot, top[u] = Top; if (tid[sun[u]] == -1) dfs1(sun[u], d+1, Top); for (i = 0;i < V[u].size();i++) { v = V[u][i]; if (tid[v] != -1) continue; dfs1(v, d+1, v); }}void Push(int d) { tr[d].sum = tr[lc].sum+tr[rc].sum; tr[d].mx = max(tr[lc].mx, tr[rc].mx);}void build(int d, int l, int r) { if (l == r) { tr[d].mx = tr[d].sum = val[l]; return; } build(lc, l, mid), build(rc, mid+1, r); Push(d);}void update(int d, int l, int r, int pos, int v) { if (l == r && pos == l) { tr[d].mx = tr[d].sum = v; return; } if (pos <= mid) update(lc, l, mid, pos, v); else update(rc, mid+1, r, pos, v); Push(d);}int query(int d, int l, int r, int L, int R, int k) { if (l == L && r == R) { if (k) return tr[d].mx; return tr[d].sum; } if (R <= mid) return query(lc, l, mid, L, R, k); else if (L > mid) return query(rc, mid+1, r, L, R, k); else { if (k) return max(query(lc, l, mid, L, mid, k), query(rc, mid+1, r, mid+1, R, k)); else return query(lc, l, mid, L, mid, k)+query(rc, mid+1, r, mid+1, R, k); }}int M(int u, int v, int k) { int re = 0, tm; if (k) re = -inf; while (top[u] != top[v]) { if (dep[top[u]] < dep[top[v]]) swap(u, v); tm = query(1, 1, tot, tid[top[u]], tid[u], k); if (k) re = max(tm, re); else re += tm; u = fa[top[u]]; } if (tid[u] > tid[v]) swap(u, v); tm = query(1, 1, tot, tid[u], tid[v], k); if (k) re = max(tm, re); else re += tm; return re;}int main() { int i, j, u, v, m; char w[10]; while (~scanf("%d", &n)) { for (i = 1;i <= n;i++) V[i].clear(); for (i = 1;i < n;i++) { scanf("%d%d", &u, &v); V[u].push_back(v), V[v].push_back(u); } memset(tid, -1, sizeof(tid)); tot = 0; for (i = 1;i <= n;i++) scanf("%d", &tmp[i]); dfs(1, -1); dfs1(1, 0, 1); for (i = 1;i <= n;i++) val[tid[i]] = tmp[i]; build(1, 1, tot); scanf("%d", &m); while (m--) { scanf("%s%d%d", w, &u, &v); if (w[0] == 'C') { update(1, 1, tot, tid[u], v); }else if (w[1] == 'M') { printf("%d\n", M(u, v, 1)); }else printf("%d\n", M(u, v, 0)); } }}
0 0
- 【TOJ 3701.】A Pungent Problem【树链刨分】
- TOJ A+B Problem
- TOJ 4107 A simple problem
- TOJ 2793.A Simple Problem
- ACM TOJ 1283 A DP Problem
- TOJ 2199 A+B Problem的无奈 2006-07-21
- TOJ 1283 A DP Problem 字符串处理,搜索
- TOJ 10006 Josephus Problem
- TOJ 3761 Egg Problem
- toj 2867. Picking Problem
- TOJ 4112 Counting problem
- TOJ 2821.Grouping Problem
- TOJ 1753.Hamming Problem
- Toj 3777 Function Problem
- TOJ 4110 A+B
- TOJ 4109 Cyuunibyou's problem
- TOJ 1154. A Mathematical Curiosity
- toj 4611 Repairing a Road
- linux学习之定时跑任务
- 11111111111111
- CI模板中php脚本的使用
- Git 版本管理工具(一)
- linux screen 详解
- 【TOJ 3701.】A Pungent Problem【树链刨分】
- 卸载virbr0
- Git 常用命令详解(二)
- GSM WCDMA CDMA 意思区别比较
- c++运算符重载总结
- sort命令使用
- jsp Request获取url信息的各种方法比较
- Install redis on CentOS6.5
- 职业选择测试(A/B卷)