1 条题解
-
0

#include <bits/stdc++.h> typedef long long ll; const int N = 400054, M = N * 2; int n, E = 0; int to[M], first[N], next[M]; int p[N], prf[N]; ll a[N], sa[N], f[N]; ll ans = 0; inline ll min(const ll x, const ll y) {return x < y ? x : y;} inline ll max(const ll x, const ll y) {return x < y ? y : x;} inline void addedge(int u, int v) { to[++E] = v, next[E] = first[u], first[u] = E; to[++E] = u, next[E] = first[v], first[v] = E; } // V : a[] + virtual sum (v + as) // sa : sum of V (s + st, sum of v + sum of as) namespace LCT { #define pa p[nd] struct node {ll v, sa; int p, c[2];} nd[N]; inline int dir(int x) {return !nd[x].p ? -1 : x == nd[x].pa.c[0] ? 0 : x == nd[x].pa.c[1] ? 1 : -1;} inline void update(int x) {const int l = nd[x].c[0], r = nd[x].c[1]; nd[x].sa = nd[x].v + nd[l].sa + nd[r].sa;} void rotate(int x) { int y = nd[x].p, d = !dir(x); nd[nd[y].c[!d] = nd[x].c[d]].p = y; nd[x].p = nd[y].p; if (~dir(y)) nd[y].pa.c[dir(y)] = x; nd[nd[x].c[d] = y].p = x; update(y); } void splay(int x) {for (; ~dir(x); rotate(x)) if (~dir(nd[x].p)) rotate(dir(x) ^ dir(nd[x].p) ? x : nd[x].p); update(x);} void access(int x, int val) { a[x] += val; for (int r, y = 0; x; y = x, x = nd[x].p) { splay(x), r = nd[x].c[1]; nd[x].v += val, nd[x].sa += val; ll sum = nd[x].v + nd[r].sa; if (r && nd[r].sa * 2 <= sum) nd[x].v += nd[r].sa, nd[x].c[1] = 0; if (y && nd[y].sa * 2 > sum) nd[x].v -= nd[y].sa, nd[x].c[1] = y; ans -= f[x], ans += f[x] = min(sum - 1, 2 * (sum - max(a[x], nd[x].c[1][nd].sa))); update(x); } } } void dfs(int x) { int i, y, &z = prf[x]; sa[x] = a[x]; for (i = first[x]; i; i = next[i]) if ((y = to[i]) != p[x]) p[y] = x, dfs(y), sa[x] += sa[y], sa[y] > sa[z] ? z = y : 0; ans += f[x] = min(sa[x] - 1, 2 * (sa[x] - max(a[x], sa[z]))); } int main() { int i, u, v, q; scanf("%d%d", &n, &q); for (i = 1; i <= n; ++i) scanf("%lld", a + i); for (i = 1; i < n; ++i) scanf("%d%d", &u, &v), addedge(u, v); dfs(1), printf("%lld\n", ans); for (i = 1; i <= n; ++i) { LCT::nd[i].p = p[i], LCT::nd[i].v += LCT::nd[i].sa = sa[i]; if (sa[prf[i]] * 2 > sa[i]) LCT::nd[i].c[1] = prf[i], LCT::nd[i].v -= sa[prf[i]]; } for (; q; --q) scanf("%d%d", &u, &v), LCT::access(u, v), printf("%lld\n", ans); return 0; }
- 1
信息
- ID
- 1485
- 时间
- 2000ms
- 内存
- 512MiB
- 难度
- 6
- 标签
- 递交数
- 75
- 已通过
- 26
- 上传者