树链剖分模板
模板题:洛谷2590
#include<cstdio> #include<iostream> using namespace std; const int maxn = 30010; inline int qread(){ register int ch = getchar(), x = 0, flag = 0; while(ch < '0' || ch > '9') {if(ch == '-') flag = 1; ch = getchar();} while(ch >= '0' && ch <= '9') x = (x << 3) + (x << 1) + ch - 48, ch = getchar(); return flag ? -x : x; } int head[maxn]; int go[maxn << 1]; int nxt[maxn << 1]; int n, q; int val[maxn]; int son[maxn]; int deep[maxn]; int f[maxn]; int size[maxn]; int top[maxn]; int seg[maxn]; int rev[maxn]; int sum[maxn << 2]; int maxx[maxn << 2]; void dfs1(int x){ size[x] = 1; for(register int i = head[x]; i; i =nxt[i]){ if(!deep[go[i]]){ f[go[i]] = x; deep[go[i]] = deep[x] + 1; dfs1(go[i]); size[x] += size[go[i]]; if(size[go[i]] > size[son[x]]) son[x] = go[i]; } } } void dfs2(int x){ if(son[x]){ top[son[x]] = top[x]; seg[son[x]] = ++seg[0]; rev[seg[0]] = son[x]; dfs2(son[x]); } for(register int i = head[x]; i; i = nxt[i]){ if(!top[go[i]]){ top[go[i]] = go[i]; seg[go[i]] = ++seg[0]; rev[seg[0]] = go[i]; dfs2(go[i]); } } } inline void update(int x){ sum[x] = sum[x << 1] + sum[x << 1 | 1]; maxx[x] = max(maxx[x << 1], maxx[x << 1 | 1]); } void build(int x, int l, int r){ if(l == r){ sum[x] = maxx[x] = val[rev[l]]; return; } int mid = (l + r) >> 1; build(x << 1, l, mid); build(x << 1 | 1, mid + 1, r); update(x); } int SUM, MAX; void change(int l, int r, int P, int v, int x){ if(l == r){ maxx[x] = sum[x] = v; return ; } int mid = (l + r) >> 1; if(P <= mid) change(l, mid, P, v, x << 1); else change(mid + 1, r, P, v, x << 1 | 1); update(x); } void ask(int l, int r, int L, int R, int x){ if(L <= l && R >= r){ SUM += sum[x]; MAX = max(MAX, maxx[x]); return ; } int mid = (l + r) >> 1; if(mid >= L) ask(l, mid, L, R, x << 1); if(mid < R) ask(mid + 1, r, L, R, x << 1 | 1); } void asktree(int x, int y){ int fx = top[x], fy = top[y]; while(fx != fy){ if(deep[fx] < deep[fy]) swap(x, y), swap(fx, fy); ask(1, n, seg[fx], seg[x], 1); x = f[fx]; fx = top[x]; } if(deep[x] > deep[y]) swap(x, y); ask(1, n, seg[x], seg[y], 1); } void init(){ n = qread(); for(int i = 1; i < n; ++i){ int x = qread(), y = qread(); go[i] = y; nxt[i] = head[x]; head[x] = i; go[i + n] = x; nxt[i + n] = head[y]; head[y] = n + i; } for(int i = 1; i <= n; ++i) val[i] = qread(); q = qread(); rev[1] = top[1] = seg[0] = seg[1] = deep[1] = 1; dfs1(1); dfs2(1); build(1, 1, n); } int main(void){ init(); while(q--){ string op; cin >> op; if(op == "QMAX"){ int x = qread(), y = qread(); MAX = 0x80000000; asktree(x, y); printf("%d\n", MAX); } else if(op == "QSUM"){ int x = qread(), y = qread(); SUM = 0; asktree(x, y); printf("%d\n", SUM); } else{ int x = qread(), v = qread(); change(1, n, seg[x], v, 1); } } }