1 条题解

  • 0
    @ 2026-1-12 17:49:32

    #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
    上传者