树剖板子20分求助
查看原帖
树剖板子20分求助
254733
Night_Bringer楼主2021/4/3 14:32
#include <cstdio>
#include <algorithm>
using namespace std;
const int MAXN = 1e6 + 5;
#define INF 0x3f3f3f3f
struct Segment_Tree {
	int Left, Right, Max_Data, Sum_Data, Lazy_Tag;
	#define LC(x) (x << 1)
	#define RC(x) (x << 1 | 1)
	#define L(x) tree[x].Left
	#define R(x) tree[x].Right
	#define T(x) tree[x].Lazy_Tag
	#define A(x) tree[x].Max_Data
	#define S(x) tree[x].Sum_Data
};
Segment_Tree tree[MAXN << 2];
struct Edge {
	int Next, To;
};
Edge edge[MAXN << 1];
int head[MAXN];
int edgetot = 1;
int dfn[MAXN], dep[MAXN], siz[MAXN], son[MAXN], tp[MAXN], fa[MAXN];
int w[MAXN];
int n, q;
int tim;
void Addedge(int x, int y) {
	edge[++edgetot].Next = head[x], edge[edgetot].To = y, head[x] = edgetot;
	edge[++edgetot].Next = head[y], edge[edgetot].To = x, head[y] = edgetot;
}
void Push_Up(int pos) {
	S(pos) = S(LC(pos)) + S(RC(pos));
	A(pos) = max(A(LC(pos)), A(RC(pos)));
}
void Build(int pos, int l, int r) {
	L(pos) = l;
	R(pos) = r;
	if(l == r)
		return;
	int mid = (l + r) >> 1;
	Build(LC(pos), l, mid);
	Build(RC(pos), mid + 1, r);
}
void Update(int pos, int x, int k) {
	if(L(pos) == R(pos)) {
		A(pos) = S(pos) = k;
		return;
	}
	if(R(LC(pos)) >= x)
		Update(LC(pos), x, k);
	else
		Update(RC(pos), x, k);
	Push_Up(pos);
}
int Query_Max(int pos, int l, int r) {
	if(l <= L(pos) && R(pos) <= r)
		return A(pos);
	int res = -INF;
	if(R(LC(pos)) >= l)
		res = max(res, Query_Max(LC(pos), l, r));
	if(L(RC(pos)) <= r)
		res = max(res, Query_Max(RC(pos), l, r));
	return res;
}
int Max_Past(int x, int y) {
	int res = -INF;
	while(tp[x] != tp[y]) {
		if(dep[tp[x]] < dep[tp[y]])
			swap(x, y);
		res = max(res, Query_Max(1, dfn[tp[x]], dfn[x]));
		x = fa[tp[x]];
	}
	if(dep[x] > dep[y])
		swap(x, y);
	res = max(res, Query_Max(1, dfn[x], dfn[y]));
	return res;
}
int Query_Sum(int pos, int l, int r) {
	if(l <= L(pos) && R(pos) <= r)
		return S(pos);
	int res = 0;
	if(R(LC(pos)) >= l)
		res += Query_Sum(LC(pos), l, r);
	if(L(RC(pos)) <= r)
		res += Query_Sum(RC(pos), l, r);
	return res;
}
int Sum_Past(int x, int y) {
	int res = 0;
	while(tp[x] != tp[y]) {
		if(dep[tp[x]] < dep[tp[y]])
			swap(x, y);
		res += Query_Sum(1, dfn[tp[x]], dfn[x]);
		x = fa[tp[x]];
	}
	if(dep[x] > dep[y])
		swap(x, y);
	res += Query_Sum(1, dfn[x], dfn[y]);
	return res;
}
void dfs1(int u, int pre) {
	dep[u] = dep[pre] + 1;
	fa[u] = pre;
	siz[u] = 1;
	int maxn = -INF;
	for(int i = head[u]; i; i = edge[i].Next) {
		int v = edge[i].To;
		if(v != pre) {
			dfs1(v, u);
			siz[u] += siz[v];
			if(siz[v] > maxn) {
				son[u] = v;
				maxn = siz[v];
			}
		}
	}
}
void dfs2(int u, int Top) {
	dfn[u] = ++tim;
	tp[u] = Top;
	if(son[u])
		dfs2(son[u], Top);
	for(int i = head[u]; i; i = edge[i].Next) {
		int v = edge[i].To;
		if(v != son[u] && v != fa[u])
			dfs2(v, v);
	}
}
int main() {
	scanf("%d", &n);
	for(int i = 1, a, b; i < n; i++) {
		scanf("%d %d", &a, &b);
		Addedge(a, b);
	}
	dfs1(1, 0);
	dfs2(1, 1);
	Build(1, 1, tim);
	for(int i = 1; i <= n; i++) {
		scanf("%d", &w[i]);
		Update(1, dfn[i], w[i]);
	}
	char opt[10];
	int u, v;
	for(scanf("%d", &q); q; q--) {
		scanf("%s", opt);
		scanf("%d %d", &u, &v);
		if(opt[0] == 'C')
			Update(1, u, v);
		else if(opt[1] == 'M')
			printf("%d\n", Max_Past(u, v));
		else
			printf("%d\n", Sum_Past(u, v));
	}
	return 0;
}
2021/4/3 14:32
加载中...