玩原神玩多了 树链剖分不过样例求调 我是胡桃的狗
查看原帖
玩原神玩多了 树链剖分不过样例求调 我是胡桃的狗
303531
ReverBer楼主2023/8/10 10:15
#include <bits/stdc++.h>

using namespace std;
#define int long long
typedef long long ll;
const int MAX = 1e6 + 10;
int n, m;
int w[MAX];
int from, to;
int op, x, a;
int t1[MAX << 2], t2[MAX << 2];
vector <int > edge[MAX];
namespace BIT {
	inline int lowbit(int x) {
		return x & (-x);
	}
	inline void add1(int x, int k) {
		for (int i = x; i <= n; i += lowbit(i)) {
			t1[i] += k;
			t2[i] += k * x;
		}
	}
	inline void add(int l, int r, int k) {
		add1(l, k);
		add1(r + 1, -k);
	}
	inline int query1(int x) {
		ll res = 0;
		for (int i = x; i; i -= lowbit(i)) {
			res += t1[i] * (x + 1);
			res -= t2[i];
		}
		return res;
	}
	inline int query(int l, int r) {
		return query1(r) - query1(l - 1);
	}
}
int fa[MAX], dep[MAX], size[MAX], son[MAX], id[MAX], top[MAX];
int cnt;
namespace dfs {
	void dfs1(int now, int f) {
		fa[now] = f;
		dep[now] = dep[f] + 1;
		size[now] = 1;
		int maxson = -1;
		for (auto &&e : edge[now]) {
			if (e == f) continue;
			size[now] += size[e];
			if (size[e] > maxson) {
				maxson = size[e];
				son[now] = e;
			}
		}
	}
	void dfs2(int now, int tp) {
		top[now] = tp;
		id[now] = ++cnt;
		if (w[now]) BIT::add(id[now], id[now], w[now]);
		if (!son[now]) return;
		dfs2(son[now], tp);
		for (auto &&e : edge[now]) {
			if (e == son[now] or e == fa[now]) continue;
			dfs2(e, e);
		}
	}
}
namespace yuanshen {
	void addpoint(int x, int k) {
		BIT::add(id[x], id[x], k);
	}
	void addsub(int x, int k) {
		BIT::add(id[x], id[x] + size[x] - 1, k);
	}
	int queryPath(int u, int v) {
		int res = 0;
		while (top[v] != top[u]) {
			if (dep[top[u]] < dep[top[v]]) swap(u, v);
			res = (res + BIT::query(id[top[u]], id[u]));
			u = fa[top[u]];
		}
		if (dep[u] > dep[v]) swap(u, v);
		res = (res + BIT::query(id[u], id[v]));
		return res;
	}
}
signed main() {
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	cin >> n >> m;
	for (register int i = 1; i <= n; i++) cin >> w[i];
	for (register int i = 1; i < n; i++) {
		cin >> from >> to;
		edge[from].push_back(to);
		edge[to].push_back(from);
	}
	dfs::dfs1(1, 0);
	dfs::dfs2(1, 1);
	while (m--) {
		cin >> op;
		if (op == 1) {
			cin >> x >> a;
			yuanshen::addpoint(x, a);
		} else if (op == 2) {
			cin >> x >> a;
			yuanshen::addsub(x, a);
		} else {
			cin >> x;
			cout<<yuanshen::queryPath(1,x)<<'\n';
			//cout << 1 << '\n';
		}
	}
	return 0;
}
2023/8/10 10:15
加载中...