树剖样例没过求条
查看原帖
树剖样例没过求条
923248
Lian_zy楼主2024/4/21 18:02

rt,求神犇看看

#include <vector>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define ll long long
using namespace std;

const int maxn = 1e5 + 10;
struct node {
	int l, r;
	ll val, tag;
} tree[maxn << 2];
vector<int> G[maxn];
int n, m, u, v, op, a[maxn], d[maxn], f[maxn], bel[maxn], dfn[maxn], siz[maxn], son[maxn], top[maxn];
void dff(int u, int fa) {
	f[u] = fa;
	siz[u] = 1;
	d[u] = d[fa] + 1;
	for (auto v : G[u]) {
		if (v == fa) continue;
		dff(v, u);
		siz[u] += siz[v];
		if (siz[son[u]] < siz[v]) son[u] = v;
	}
	return ;
}
void dfs(int u, int x) {
	top[u] = x;
	dfn[u] = ++op;
	bel[dfn[u]] = u;
	if (son[u]) dfs(son[u], x);
	for (auto v : G[u]) {
		if (v == f[u] || v == son[u]) continue;
		dfs(v, v);
	}
	return ;
}
void tag(int u, ll k) {
	tree[u].tag += k;
	tree[u].val += (tree[u].r - tree[u].l + 1) * k;
	return ;
}
void push_up(int u) {
	tree[u].val = tree[u << 1].val + tree[u << 1 | 1].val;
	return ;
}
void push_down(int u) {
	tag(u << 1, tree[u].tag);
	tag(u << 1 | 1, tree[u].tag);
	tree[u].tag = 0;
	return ;
}
void build(int u, int l, int r) {
	tree[u].l = l;
	tree[u].r = r;
	if (l == r) {
		tree[u].val = a[bel[l]];
		return ;
	}
	int mid = l + r >> 1;
	build(u << 1, l, mid);
	build(u << 1 | 1, mid + 1, r);
	push_up(u);
	return ;
}
void update(int u, int x, int y, ll k) {
	if (tree[u].r < x || y < tree[u].l) return ;
	if (tree[u].l <= x && y <= tree[u].r) {
		tag(u, k);
		return ;
	}
	int mid = tree[u].l + tree[u].r >> 1;
	push_down(u);
	update(u << 1, x, y, k);
	update(u << 1 | 1, x, y, k);
	push_up(u);
	return ;
}
ll getsum(int u, int x, int y) {
	if (tree[u].r < x || y < tree[u].l) return 0;
	if (tree[u].l <= x && y <= tree[u].r) return tree[u].val;
	int mid = tree[u].l + tree[u].r >> 1;
	push_down(u);
	return getsum(u << 1, x, y) + getsum(u << 1 | 1, x, y);
}
ll query(int x, int y) {
	if (d[x] > d[y]) swap(x, y);
	if (top[x] == top[y]) return getsum(1, dfn[x], dfn[y]);
	return query(x, f[top[y]]) + getsum(1, dfn[top[x]], dfn[x]);
}
int main() {
	scanf("%d %d", &n, &m);
	for (int i = 1; i <= n; i++) scanf("%d", a + i);
	for (int i = 1; i < n; i++) {
		scanf("%d %d", &u, &v);
		G[u].push_back(v);
		G[v].push_back(u);
	}
	dff(1, 0);
	dfs(1, 1);
	build(1, 1, n);
	while (m--) {
		scanf("%d %d", &op, &u);
		if (op == 1) {
			scanf("%d", &v);
			update(1, dfn[u], dfn[u], v);
		} else if (op == 2) {
			scanf("%d", &v);
			update(1, dfn[u], dfn[u] + siz[u] - 1, v);
		} else printf("%lld\n", query(1, u));
	}
	return 0;
}
2024/4/21 18:02
加载中...