A tree is given with the point weights. There are three operations: I C1 C2 K: add KD C1 C2 K to all vertices in the C1 and C2 paths: subtract all vertices in the C1 and C2 paths from kq c: query the Weight Analysis of node number C: Typical tree link partitioning questions. Split them first, and then use the line segment tree for maintenance. Note that hdu oj uses a Windows system, STACK explosion is easy, so add: # pragma comment (linker, "/STACK: 1024000000,1024000000") before the code to manually expand the STACK.
# Pragma comment (linker, "/STACK: 1024000000,1024000000") # include <iostream> # include <string. h> # include <algorithm> # include <stdio. h ># include <vector> using namespace std; const int N = 50010; int n, m, Q; int tim; int num [N], siz [N], top [N], son [N]; int dep [N], tid [N], rank [N], fa [N]; int head [N], to [2 * N], next [2 * N], edge; void Init () {memset (head,-1, sizeof (head); memset (son, -1, sizeof (son); tim = 0; edge = 0;} void addedge (Int u, int v) {to [edge] = v, next [edge] = head [u], head [u] = edge ++; to [edge] = u, next [edge] = head [v], head [v] = edge ++;} // void dfs1 (int u, int father, int d) {dep [u] = d; fa [u] = father; siz [u] = 1; for (int I = head [u]; ~ I; I = next [I]) {int v = to [I]; if (v! = Father) {dfs1 (v, u, d + 1); siz [u] + = siz [v]; if (son [u] =-1 | siz [v]> siz [son [u]) son [u] = v ;}}} void dfs2 (int u, int tp) {top [u] = tp; tid [u] = ++ tim; rank [tid [u] = u; if (son [u] =-1) return; dfs2 (son [u], tp); for (int I = head [u]; ~ I; I = next [I]) {int v = to [I]; if (v! = Son [u] & v! = Fa [u]) dfs2 (v, v) ;}// segment tree part # define lson l, mid, rt <1 # define rson mid + 1, r, rt <1 | 1int sum [4 * N], col [4 * N]; void PushUP (int rt) {sum [rt] = max (sum [rt <1], sum [rt <1 | 1]);} void PushDown (int rt, int m) {if (col [rt]) {col [rt <1] + = col [rt]; col [rt <1 | 1] + = col [rt]; sum [rt <1] + = (m-(m> 1) * col [rt]; sum [rt <1 | 1] + = (m> 1) * col [rt]; col [rt] = 0 ;}} void Build (int l, int r, int rt) {col [rt] = 0; if (l = r) {sum [rt] = num [rank [l]; re Turn;} int mid = (l + r)> 1; Build (lson); Build (rson); PushUP (rt);} void Update (int L, int R, int v, int l, int r, int rt) {if (L <= l & R> = r) {col [rt] + = v; sum [rt] + = v * (r-l + 1); return;} PushDown (rt, r-l + 1); int mid = (l + r)> 1; if (L <= mid) Update (L, R, v, lson); if (R> mid) Update (L, R, v, rson ); pushUP (rt);} int Query (int l, int r, int rt, int val) {if (l = r) return sum [rt]; PushDown (rt, r-l + 1); int mid = (l + r)> 1; int ret = 0; if (Val <= mid) ret = Query (lson, val); else ret = Query (rson, val); PushUP (rt); return ret;} void Change (int x, int y, int val) {while (top [x]! = Top [y]) {if (dep [top [x] <dep [top [y]) swap (x, y ); update (tid [top [x], tid [x], val, 1, n, 1); x = fa [top [x];} if (dep [x]> dep [y]) swap (x, y); Update (tid [x], tid [y], val, 1, n, 1) ;}int main () {char character [5]; int a, B, c; while (~ Scanf ("% d", & n, & m, & Q) {Init (); for (int I = 1; I <= n; I ++) scanf ("% d", & num [I]); for (int I = 1; I <= m; I ++) {scanf ("% d", & a, & B); addedge (a, B);} dfs1 (1, 0, 0); dfs2 (1, 1 ); build (1, n, 1); while (Q --) {scanf ("% s", rows); if (rows [0] = 'q ') {scanf ("% d", & a); printf ("% d \ n", Query (1, n, 1, tid [a]);} else {scanf ("% d", & a, & B, & c); if (else [0] = 'D') c =-c; change (a, B, c) ;}} return 0 ;}