萌新刚学DDP球调,已经调了1.14514秒了,样例莓過
查看原帖
萌新刚学DDP球调,已经调了1.14514秒了,样例莓過
871641
封禁用户楼主2023/4/30 19:44
#include<bits/stdc++.h>
using namespace std;
const int maxn = 5e5 + 5;
const int inf = INT_MAX;
const int matrix_size = 2;
int n, m;
int head[maxn], nxt[maxn], to[maxn], tot;
void add(int u, int v) {
	to[++tot] = v;
	nxt[tot] = head[u];
	head[u] = tot;
}
int siz[maxn], son[maxn], top[maxn], fa[maxn], dep[maxn], dfn[maxn], id[maxn], ed[maxn];
int idx;
int a[maxn], f[maxn][2];
struct matrix {
	int g[matrix_size][matrix_size];
	matrix() {
		memset(g, 0, sizeof(g));
	} matrix operator*(const matrix&b)const {
		matrix sum;
		for (int i = 0; i <= 1; i++) {
			for (int j = 0; j <= 1; j++) {
				for (int k = 0; k <= 1; k++) {
					sum.g[i][j] = max(sum.g[i][j], g[i][k] + b.g[k][j]);
				}
			}
		}
		return sum;
	}
} tree[maxn], g[maxn];
int ls(int o) {
	return o << 1;
}
int rs(int o) {
	return o << 1 | 1;
}
void push_up(int rt) {
	tree[rt] = tree[ls(rt)] * tree[rs(rt)];
}
void build(int rt, int l, int r) {
	if (l == r) {
		tree[rt] = g[id[l]];
		return;
	}
	int mid = (l + r) >> 1;
	build(ls(rt), l, mid);
	build(rs(rt), mid + 1, r);
	push_up(rt);
}
matrix ask(int rt, int l, int r, int ql, int qr) {
	if (ql <= l && r <= qr) {
		return tree[rt];
	}
	int mid = (l + r) >> 1;
	if (qr <= mid) {
		return ask(ls(rt), l, mid, ql, qr);
	}
	if (mid < ql) {
		return ask(rs(rt), mid + 1, r, ql, qr);
	}
	return ask(ls(rt), l, mid, ql, qr) * ask(rs(rt), mid + 1, r, ql, qr);
}
inline void change(int rt, int l, int r, int pos) {
	if (l == r) {
		tree[rt] = g[id[l]];
		return;
	}
	int mid = (l + r) >> 1;
	if (pos <= mid) {
		change(ls(rt), l, mid, pos);
	} else {
		change(rs(rt), mid + 1, r, pos);
	}
	push_up(rt);
}
void update(int x, int val) {
	g[x].g[1][0] += val - a[x];
	a[x] = val;
	while (x) {
		matrix last = ask(1, 1, n, dfn[top[x]], ed[top[x]]);
		change(1, 1, n, dfn[x]);
		matrix now = ask(1, 1, n, dfn[top[x]], ed[top[x]]);
		x = fa[top[x]];
		g[x].g[0][0] += max(now.g[0][0], now.g[1][0]) - max(last.g[0][0], last.g[1][0]);
		g[x].g[0][1] = g[x].g[0][0];
		g[x].g[1][0] += now.g[0][0] - last.g[0][0];
	}
}
void dfs1(int u) {
	int weight = 0;
	siz[u] = 1;
	f[u][1] = a[u];
	for (int i = head[u]; i != 0; i = nxt[i]) {
		int v = to[i];
		if (v == fa[u]) {
			continue;
		}
		dep[v] = dep[u] + 1;
		fa[v] = u;
		dfs1(v);
		siz[u] += siz[v];
		if (siz[v] > weight) {
			weight = siz[v];
			son[u] = v;
		}
		f[u][1] += f[v][0];
		f[u][0] += max(f[v][0], f[v][1]);
	}
}
void dfs2(int u, int list_Top) {
	top[u] = list_Top;
	dfn[u] = ++idx;
	id[idx] = u;
	ed[list_Top] = idx;
	g[u].g[1][0] = a[u];
	g[u].g[1][1] = -inf;
	if (!son[u]) {
		return;
	}
	dfs2(son[u], list_Top);
	for (int i = head[u]; i != 0; i = nxt[i]) {
		int v = to[i];
		if (v == fa[u] || v == son[u]) {
			continue;
		}
		dfs2(v, v);
		g[u].g[0][0] += max(f[v][0], f[v][1]);
		g[u].g[1][0] += f[v][0];
	}
	g[u].g[0][1] = g[u].g[0][0];
}
signed main() {
	cin >> n >> m;
	for (int i = 1; i <= n; i++) {
		cin >> a[i];
	}
	for (int i = 1; i < n; i++) {
		int s, t;
		cin >> s >> t;
		add(s, t);
		add(t, s);
	}
	dep[1] = 1;
	dfs1(1);
	dfs2(1, 1);
	build(1, 1, n);
	for (int i = 1; i <= m; i++) {
		int x;
		int val;
		cin >> x >> val;
		update(x, val);
		matrix ans = ask(1, 1, n, 1, ed[1]);
		cout << max(ans.g[0][0], ans.g[1][0]) << endl;
	}
	return 0;
}
2023/4/30 19:44
加载中...