树剖 RE 50pts 求助
查看原帖
树剖 RE 50pts 求助
908514
DHT666楼主2024/12/28 14:22

rt,好像很多人都在讨论区里问了,但我没找到想要的回答。

xiexie

#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;

typedef long long LL;

const LL N = 1e5 + 10;

LL n, q;
LL e[N], ne[N], h[N], idx;
LL fa[N], son[N], siz[N], dep[N];
LL top[N], id[N], num;
LL tree[N * 4], tag[N * 4];

void add(LL x, LL y) {
	e[++idx] = y;
	ne[idx] = h[x];
	h[x] = idx;
}

void dfs1(LL u, LL fath) {
	fa[u] = fath;
	siz[u] = 1;
	dep[u] = dep[fath] + 1;
	int t = 0;
	for(LL i = h[u];i;i = ne[i]) {
		LL v = e[i];
		if(v == fath) continue;
		dfs1(v, u);
		siz[u] += siz[v];
		if(siz[v] > siz[son[u]]) {
			son[u] = v;
		}
	}
}

void dfs2(LL u, LL topu) {
	id[u] = ++num;
	top[u] = topu;
	if(!son[u]) return;
	dfs2(son[u], topu);
	for(LL i = h[u];i;i = ne[i]) {
		LL v = e[i];
		if(v == fa[u]) continue;
		if(v != son[u]) dfs2(v, v);
	}
}

void push_up(LL u) {
	tree[u] = tree[u << 1] + tree[u << 1 | 1];
}

void push_down(LL u, LL l, LL r) {
	if(tag[u]) {
		LL mid = l + r >> 1, t = tag[u];
		tree[u << 1] += t * (mid - l + 1);
		tag[u << 1] += t;
		tree[u << 1 | 1] += t * (r - mid);
		tag[u << 1 | 1] += t;
		tag[u] = 0;
	}
} 

void build(LL u, LL l, LL r) {
	if(l == r) {
		tree[u] = 0;
		return;
	}
	LL mid = l + r >> 1;
	build(u << 1, l, mid);
	build(u << 1 | 1, mid + 1, r);
	push_up(u);
}

void modify(LL u, LL l, LL r, LL L, LL R, LL d) {
	if(L <= l && r <= R) {
		tree[u] += d * (r - l + 1);
		tag[u] += d;
		return;
	}
	push_down(u, l, r);
	LL mid = l + r >> 1;
	if(L <= mid) modify(u << 1, l, mid, L, R, d);
	if(R > mid) modify(u << 1 | 1, mid + 1, r, L, R, d);
	push_up(u);
}

LL query(LL u, LL l, LL r, LL L, LL R) {
	if(L <= l && r <= R) {
		return tree[u];
	}
	push_down(u, l, r);
	LL mid = l + r >> 1, res = 0;
	if(L <= mid) res += query(u << 1, l, mid, L, R);
	if(R > mid) res += query(u << 1 | 1, mid + 1, r, L, R);
	return res;
}

void modify_range(LL u, LL v, LL d) {
	while(top[u] != top[v]) {
		if(dep[top[u]] < dep[top[u]]) swap(u, v);
		modify(1, 1, n, id[top[u]], id[u], d);
		u = fa[top[u]];
	}
	if(dep[u] > dep[v]) swap(u, v);
	modify(1, 1, n, id[u], id[v], d);
}

int main() {
	scanf("%lld", &n);
	for(LL i = 1;i < n;i++) {
		LL x, y;
		scanf("%lld%lld", &x, &y);
		add(x + 1, y + 1);
	}
	
	dfs1(1, 0);
	
	dfs2(1, 1);
	
	build(1, 1, num);
	
	scanf("%lld", &q);
	while(q--) {
		char op;
		cin >> op;
		if(op == 'A') {
			LL x, y, d;
			scanf("%lld%lld%lld", &x, &y, &d);
			modify_range(x + 1, y + 1, d);
		} else {
			LL x;
			scanf("%lld", &x);
			printf("%lld\n", query(1, 1, n, id[x + 1], id[x + 1] + siz[x + 1] - 1));
		}
	}
	
	return 0;
}
2024/12/28 14:22
加载中...