Despite being a question of water, I handed in more than 80 posts in my unremitting efforts. When I suddenly wrote it one day, it turned out to be 1a.
# Include <iostream> # include <cstdio> # include <cstring> # include <map> # include <vector> # include <stdlib. h> using namespace std; const int maxn = 33333; struct Node {int next; int to;} e [maxn * 2]; int len, z; # define lson l, mid, rt <1 # define rson mid + 1, r, rt <1 | 1int head [maxn], top [maxn], son [maxn], father [maxn], size [maxn], deep [maxn], pos [maxn], val [maxn], vis [maxn]; int sum [maxn <2], max [maxn <2]; void add (int from, Int to) {e [len]. to = to; e [len]. next = head [from]; head [from] = len ++;} void init (int x) {size [x] = 1; son [x] = 0; for (int I = head [x]; ~ I; I = e [I]. next) {int cc = e [I]. to; if (cc = father [x]) continue; deep [cc] = deep [x] + 1; father [cc] = x; init (cc ); size [x] + = size [cc]; if (size [son [x] <size [cc]) son [x] = cc ;}} void dfs (int x, int tp) {pos [x] = ++ z; vis [z] = x; top [x] = tp; if (son [x]) dfs (son [x], tp); for (int I = head [x]; I! =-1; I = e [I]. next) {int cc = e [I]. to; if (cc = father [x] | cc = son [x]) continue; dfs (cc, cc) ;}} void up (int rt) {sum [rt] = sum [rt <1] + sum [rt <1 | 1]; Max [rt] = max (Max [rt <1], max [rt <1 | 1]);} void build (int l, int r, int rt) {if (l = r) {Max [rt] = sum [rt] = val [vis [l]; return;} int mid = (l + r)> 1; build (lson ); build (rson); up (rt);} void update (int key, int ans, int l, int r, Int rt) {if (l = r) {Max [rt] = sum [rt] = ans; return;} int mid = (l + r)> 1; if (key <= mid) update (key, ans, lson); else update (key, ans, rson); up (rt) ;}int ask_max (int L, int R, int l, int r, int rt) {if (L <= l & r <= R) return Max [rt]; int ans =-1e9; int mid = (l + r)> 1; if (L <= mid) ans = max (ans, ask_max (L, R, lson )); if (R> mid) ans = max (ans, ask_max (L, R, rson); return ans;} int Ask_sum (int L, int R, int l, int r, int rt) {if (L <= l & r <= R) return sum [rt]; int ans = 0; int mid = (l + r)> 1; if (L <= mid) ans + = ask_sum (L, R, lson ); if (R> mid) ans + = ask_sum (L, R, rson); return ans;} void gao_max (int x, int y) {int ans =-1e9; int fx = top [x]; int fy = top [y]; while (fx! = Fy) {if (deep [fx] <deep [fy]) {swap (x, y); swap (fx, fy);} ans = max (ans, ask_max (pos [fx], pos [x], 1, z, 1); x = father [fx]; fx = top [x];} if (deep [x]> deep [y]) {swap (x, y);} ans = max (ans, ask_max (pos [x], pos [y], 1, z, 1); printf ("% d \ n", ans);} void gao_sum (int x, int y) {int ans = 0; int fx = top [x]; int fy = top [y]; while (fx! = Fy) {if (deep [fx] <deep [fy]) {swap (x, y); swap (fx, fy );} ans + = ask_sum (pos [fx], pos [x], 1, z, 1); x = father [fx]; fx = top [x];} if (deep [x]> deep [y]) swap (x, y); ans + = ask_sum (pos [x], pos [y], 1, z, 1); printf ("% d \ n", ans);} int main () {int n; int a, B, c; int q; char str [1000]; while (cin> n) {len = z = 0; memset (head,-1, sizeof (head); for (int I = 0; I <n-1; I ++) {cin> a> B; add (a, B); add (B, a) ;}for (int I = 1; I <= n; I ++) {scanf ("% d", & val [I]);} init (1); dfs (1, 1); build (1, z, 1); cin> q; while (q --) {scanf ("% s % d", str, & a, & B); if (strcmp (str, "QMAX") = 0) {gao_max (a, B);} else if (strcmp (str, "QSUM") = 0) {gao_sum (, b);} else update (pos [a], B, 1, z, 1);} return 0 ;}
1036: [ZJOI2008] Count tree segmentation