求助一道树剖的题目(基本是模板)
查看原帖
求助一道树剖的题目(基本是模板)
475831
Starry_sky700楼主2023/1/29 12:34

P3178 [HAOI2015]树上操作 样例没过,luogu提交中RE。

#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 5;
#define int long long 
int n, q, x, y, z, opt, a[N], b[N];
namespace ordinary {
	inline void chkmax(int &x, int y) {x = max(x, y);}
	inline void chkmin(int &x, int y) {x = min(x, y);}
	template <typename T> inline void read(T &x){
		x = 0; int f = 1; char ch = getchar();
		while (!isdigit(ch)) {if (ch == '-') f = -1; ch = getchar();}
		while (isdigit(ch)) {x = x * 10 + ch - '0'; ch = getchar();}
		x *= f;
	}
	template<typename _T, typename ...Args> inline void read (_T &x, Args &...args) { read(x), read(args...); }
	template<typename T_> inline void write(T_ x) {
		if (x < 0) putchar('-'), x = -x;
		if (9 < x) write(x / 10);
		putchar(x % 10 + '0');
	}
	template<typename _T, typename ...Args> inline void write (const _T &x, const Args &...args) { write(x), write(args...);} 
};
using namespace ordinary;
struct Segment_Tree {
	struct node {
		int l, r, sum, lazy;
	}t[N << 2];
	inline void pushup(int x) {t[x].sum = t[x << 1].sum + t[x << 1 | 1].sum;}
	inline void pushdown(int x) {
		if (t[x].lazy) {
			t[x << 1].sum += t[x].lazy * (t[x << 1].r - t[x << 1].l + 1);
			t[x << 1 | 1].sum += t[x].lazy * (t[x << 1 | 1].r - t[x << 1 | 1].l + 1);
			t[x << 1].lazy += t[x].lazy, t[x << 1 | 1].lazy += t[x].lazy, t[x].lazy = 0;
		}
	}
	inline void build(int x, int l, int r) {
		t[x].l = l, t[x].r = r;
		if (l == r) {
			t[x].sum = a[l];
			return ;
		}
		int mid = l + r >> 1;
		build(x << 1, l, mid), build(x << 1 | 1, mid + 1, r);
		pushup(x);
	}
	inline void update(int x, int l, int r, int val) {
		if (l <= t[x].l && t[x].r <= r) {
			t[x].sum += val * (t[x].r - t[x].l + 1), t[x].lazy += val;
			return ;
		}
		pushdown(x);
		int mid = t[x].l + t[x].r >> 1;
		if (l <= mid) update(x << 1, l, r, val);
		if (mid < r) update(x << 1 | 1, l, r, val);
		pushup(x);
	}
	inline int Get_sum(int x, int l, int r) {
		if (l <= t[x].l && t[x].r <= r) return t[x].sum;
		pushdown(x);
		int mid = t[x].l + t[x].r >> 1, ans = 0;
		if (l <= mid) ans += Get_sum(x << 1, l, r);
		if (mid < r) ans += Get_sum(x << 1 | 1, l, r);
		return ans;
	}
}T;
struct Heavy_Light_Decomposition {
	vector<int> G[N];
	int dep[N], hson[N], lens[N], fa[N], dfn[N], top[N], tot;
	inline void dfs1(int pre, int x, int cnt) {
		int len = G[x].size();fa[x] = pre, dep[x] = cnt, lens[x] = 1;
		for (int i = 0;i < len;i++) {
			if (G[x][i] == pre) continue;
			dfs1(x, G[x][i], cnt + 1);
			lens[x] += lens[G[x][i]];
			if (lens[G[x][i]] > lens[hson[x]]) hson[x] = G[x][i];
		}
	}
	inline void dfs2(int x, int cnt) {
		int len = G[x].size();top[x] = cnt, dfn[x] = ++tot;
		if (!hson[x]) return ;
		dfs2(hson[x], cnt);
		for (int i = 0;i < len;i++) {
			if (G[x][i] == fa[x] || G[x][i] == hson[x]) continue;
			dfs2(G[x][i], G[x][i]);
		}
	}
	inline int query(int x, int y) {
		int ans = 0;
		while (top[x] != top[y]) {
			if (dep[top[x]] < dep[top[y]]) swap(x, y);
			ans += T.Get_sum(1, dfn[top[x]], dfn[x]);
			x = fa[top[x]];
		}
		if (dep[x] > dep[y]) swap(x, y);
		ans += T.Get_sum(1, dfn[x], dfn[y]);
		return ans;
	}
}Tree;
signed main() {
	read(n);
	for (int i = 1;i <= n;i++) read(b[i]);
	for (int i = 1;i < n;i++) read(x, y), Tree.G[x].push_back(y), Tree.G[y].push_back(x);
	Tree.dfs1(-1, 1, 1), Tree.dfs2(1, 1);
	for (int i = 1;i <= n;i++) a[Tree.dfn[i]] = b[i];
	T.build(1, 1, n), read(q);
	while(q--) {
		read(opt, x);
		if (opt == 1) read(y), T.update(1, Tree.dfn[x], Tree.dfn[x], y);
		else if (opt == 2) read(y), T.update(1, Tree.dfn[x], Tree.dfn[x] + Tree.lens[x] - 1, y);
		else write(Tree.query(1, x)), puts("");
	}
	return 0;
}

2023/1/29 12:34
加载中...