37pts 求调
查看原帖
37pts 求调
359764
ek7a楼主2023/7/21 16:41
#include <bits/stdc++.h>
using namespace std;
#define rep(i, a, b) for (int i = (a); i <= (b); ++i)
#define int long long
const int N = 1e5 + 10;
int n, m, p;
int a[N];
vector<int> G[N];
int cnt = 0, rt;
int top[N], node[N];
int sz[N], dep[N], fa[N];
int son[N], dfn[N];
void dfs1(int u, int p) {
	sz[u] = 1;
	dep[u] = dep[p] + 1;
	fa[u] = p;
	for (int v : G[u]) {
		if (v == p) continue;
		dfs1(v, u);
		sz[u] += sz[v];
		if (sz[v] > sz[son[u]]) son[u] = v;
	}
}
void dfs2(int u, int tp) {
	top[u] = tp;
	dfn[u] = ++cnt;
	node[cnt] = u;
	if (son[u]) dfs2(son[u], tp);
	for (int v : G[u]) if (!dfn[v])
		dfs2(v, v);
}
namespace sgt {
	#define lc x << 1, l, mid
	#define rc x << 1 | 1, mid + 1, r
	#define st int x = 1, int l = 1, int r = n
	int sum[N << 2], tag[N << 2];
	void psp(int x) {
		sum[x] = sum[x << 1] + sum[x << 1 | 1];
		sum[x] %= p;
	}
	void build(st) {
		if (l == r) {
			sum[x] = a[node[l]] % p;
			return;
		}
		int mid = l + r >> 1;
		build(lc); build(rc);
		psp(x);
	}
	void pst(int x, int l, int r, int v) {
		tag[x] += v;
		tag[x] %= p;
		sum[x] += v * (r - l + 1);
		sum[x] %= p;
	}
	void psd(st) {
		if (tag[x]) {
			int mid = l + r >> 1;
			pst(lc, tag[x]); pst(rc, tag[x]);
			tag[x] = 0;
		}
	}
	void upd(int L, int R, int v, st) {
		if (l > R || r < L) return;
		if (L <= l && r <= R) {
			return pst(x, l, r, v);
		}
		psd(x, l, r);
		int mid = l + r >> 1;
		upd(L, R, v, lc); upd(L, R, v, rc);
		psp(x);
	}
	int qry(int L, int R, st) {
		if (l > R || r < L) return 0;
		if (L <= l && r <= R) return sum[x];
		psd(x, l, r);
		int mid = l + r >> 1;
		return (qry(L, R, lc) + qry(L, R, rc)) % p; 
	}
}
void mdf1(int x, int y, int v) {
	while (top[x] != top[y]) {
		if (dep[x] < dep[y]) swap(x, y);
		sgt::upd(dfn[top[x]], dfn[x], v);
		x = fa[top[x]];
	}
	if (dep[x] > dep[y]) swap(x, y);
	sgt::upd(dfn[x], dfn[y], v);
}
int qry1(int x, int y) {
	int ret = 0;
	while (top[x] != top[y]) {
		if (dep[top[x]] < dep[top[y]]) swap(x, y);
		ret = (ret + sgt::qry(dfn[top[x]], dfn[x])) % p;
		x = fa[top[x]];
	}
	if(dep[x] > dep[y]) swap(x, y);
	ret = (ret + sgt::qry(dfn[x], dfn[y])) % p;
	return ret;
}
void mdf2(int x, int v) {
	sgt::upd(dfn[x], dfn[x] + sz[x] - 1, v);
}
int qry2(int x) {
	return sgt::qry(dfn[x], dfn[x] + sz[x] - 1);
}
signed main() {
	ios::sync_with_stdio(false);
	cin.tie(nullptr);
	cin >> n >> m >> rt >> p;
	rep(i, 1, n) cin >> a[i];
	rep(i, 1, n - 1) {
		int u, v;
		cin >> u >> v;
		G[u].push_back(v);
		G[v].push_back(u);
	}
	dfs1(rt, 0);
	dfs2(rt, rt);
	sgt::build();
	rep(i, 1, m) {
		int op, x, y, z; 
		cin >> op;
		if (op == 1) {
			cin >> x >> y >> z;
			mdf1(x, y, z);
		} else if (op == 2) {
			cin >> x >> y;
			cout << qry1(x, y) << '\n';
		} else if (op == 3) {
			cin >> x >> z;
			mdf2(x, z);
		} else {
			cin >> x;
			cout << qry2(x) << '\n';
		}
	}
	return 0;
}
2023/7/21 16:41
加载中...