1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100
| #include <bits/stdc++.h> #define MAX_N 200000 #define mid ((s+t)>>1) using namespace std; typedef long long lnt; template <class T> inline void read(T &x) { x = 0; int c = getchar(), f = 1; for (; !isdigit(c); c = getchar()) if (c == 45) f = -1; for (; isdigit(c); c = getchar()) (x *= 10) += f*(c-'0'); } int n, m, a[MAX_N+5]; vector <int> G[MAX_N+5]; int ind, dep[MAX_N+5], fa[MAX_N+5], son[MAX_N+5]; int sz[MAX_N+5], top[MAX_N+5], into[MAX_N+5], outo[MAX_N+5]; lnt f[MAX_N+5], g[MAX_N+5], mxf[MAX_N+5]; struct node { lnt s, mx, lmx, rmx; node () {s = mx = lmx = rmx = 0LL;} inline friend node operator + (const node &a, const node &b) { node ret; ret.s = a.s+b.s, ret.mx = max(max(a.mx, b.mx), a.rmx+b.lmx); ret.lmx = max(a.lmx, a.s+b.lmx), ret.rmx = max(b.rmx, a.rmx+b.s); return ret; } } tr[MAX_N<<2]; struct heap { priority_queue <lnt> i, o; inline void push(lnt x) {i.push(x);} inline void pop(lnt x) {o.push(x);} inline lnt top() { while (!o.empty() && i.top() == o.top()) i.pop(), o.pop(); return i.top(); } } h[MAX_N+5]; void addedge(int u, int v) {G[u].push_back(v), G[v].push_back(u);} void DFS(int u) { sz[u] = 1; for (int i = 0; i < (int)G[u].size(); i++) { int v = G[u][i]; if (v == fa[u]) continue; dep[v] = dep[u]+1, fa[v] = u, DFS(v), sz[u] += sz[v]; if (!son[u] || sz[son[u]] < sz[v]) son[u] = v; } } void DFS(int u, int tp) { top[u] = tp, g[into[u] = ++ind] = a[u]; if (son[u]) DFS(son[u], tp); for (int i = 0, v; i < (int)G[u].size(); i++) if (((v = G[u][i]) ^ fa[u]) && (v ^ son[u])) DFS(v, v), g[into[u]] += f[v], h[into[u]].push(mxf[v]); outo[u] = son[u] ? outo[son[u]] : ind; f[u] = max(f[son[u]]+g[into[u]], 0LL); mxf[u] = max(mxf[son[u]], max(f[u], h[into[u]].top())); } void build(int v, int s, int t) { if (s == t) { tr[v].s = g[s], tr[v].mx = max(g[s], h[s].top()); tr[v].lmx = tr[v].rmx = max(g[s], 0LL); return; } build(v<<1, s, mid), build(v<<1|1, mid+1, t); tr[v] = tr[v<<1]+tr[v<<1|1]; } void modify(int v, int s, int t, int p) { if (s == t) { tr[v].s = g[s], tr[v].mx = max(g[s], h[s].top()); tr[v].lmx = tr[v].rmx = max(g[s], 0LL); return; } if (p <= mid) modify(v<<1, s, mid, p); if (p >= mid+1) modify(v<<1|1, mid+1, t, p); tr[v] = tr[v<<1]+tr[v<<1|1]; } node query(int v, int s, int t, int l, int r) { if (s >= l && t <= r) return tr[v]; node ret; if (l <= mid) ret = ret+query(v<<1, s, mid, l, r); if (r >= mid+1) ret = ret+query(v<<1|1, mid+1, t, l, r); return ret; } void change(int u, int val) { node pr, cr; pr.lmx = g[into[u]]; cr.lmx = g[into[u]]-a[u]+val; for (int i = 0; u; i++, u = fa[top[u]]) { g[into[u]] += cr.lmx-pr.lmx; if (i) h[into[u]].pop(pr.mx), h[into[u]].push(cr.mx); pr = query(1, 1, n, into[top[u]], outo[u]); modify(1, 1, n, into[u]); cr = query(1, 1, n, into[top[u]], outo[u]); } } int main() { read(n), read(m); for (int i = 1; i <= n; i++) read(a[i]), h[i].push(0); for (int i = 1, u, v; i < n; i++) read(u), read(v), addedge(u, v); DFS(1), DFS(1, 1), build(1, 1, n); while (m--) { char opt[2]; int x, y; scanf("%s", opt); if (opt[0] == 'M') read(x), read(y), change(x, y), a[x] = y; else read(x), printf("%lld\n", query(1, 1, n, into[x], outo[x]).mx); } return 0; }
|