10pts求助
查看原帖
10pts求助
1098908
dread_breaker楼主2025/1/26 09:50
#include<bits/stdc++.h>
using namespace std;

const int M = 1e5 + 5;
int n, m, rt, mod, a[M];
vector <int> G[M];

struct segment_tree {
	int tree[M * 4], tag[M * 4];
	
	int ls(int x) { return x << 1; };
	int rs(int x) { return x << 1 | 1; }
	inline void push_up(int p) { tree[p] = (tree[ls(p)] + tree[rs(p)]) % mod; }
	
	inline void change(int p, int l, int r, int k) {
		tree[p] = (tree[p] + k * (r - l + 1)) % mod;
		tag[p] = (tag[p] + k) % mod;
	}
	
	inline void push_down(int p, int l, int r) {
		if(tag[p]) {
			int mid = (l + r) >> 1;
			change(ls(p), l, mid, tag[p]), change(rs(p), mid + 1, r, tag[p]);
			tag[p] = 0;
		}
	}
	
	inline void update(int l, int r, int p, int pl, int pr, int k) {
		if(l <= pl && pr <= r) change(p, pl, pr, k);
		push_down(p, pl, pr);
		int mid = (l + r) >> 1;
		if(pl <= mid) update(l, r, ls(p), pl, mid, k);
		if(pr > mid) update(l, r, rs(p), mid + 1, pr, k);
		push_up(p);
	}
	
	int qry(int l, int r, int p, int pl, int pr) {
		if(l <= pl && pr <= r) return tree[p];
		push_down(p, pl, pr);
		int mid = (l + r) >> 1, res = 0;
		if(pl <= mid) res = (res + qry(l, r, ls(p), pl, mid)) % mod;
		if(pr > mid) res = (res + qry(l, r, rs(p), mid + 1, pr)) % mod;
		return res; 
	}
}t;

int tim, fa[M], son[M], siz[M], top[M], dfn[M], dep[M];

void dfs1(int u, int f) {
	fa[u] = f, dep[u] = dep[f] + 1;
	for(auto v : G[u]) {
		if(v == f) continue;
		dfs1(v, u), siz[u] += siz[v];
		if(son[u] == 0 || siz[son[u]] < siz[v]) son[u] = v;
	}
	siz[u]++;
}

void dfs2(int u, int f) {
	dfn[u] = ++tim;
	if(son[u]) top[son[u]] = top[u], dfs2(son[u], u);
	for(auto v : G[u]) {
		if(v == f || v == son[u]) continue;
		top[v] = v, dfs2(v, u);
	} 
}

inline void update_path(int u, int v, int k) {
	while(top[u] != top[v]) {
		if(dep[top[u]] < dep[top[v]]) swap(u, v);
		t.update(dfn[top[u]], dfn[u], 1, 1, n, k);
		u = fa[top[u]];
	}
	if(dep[u] < dep[v]) swap(u, v);
	t.update(dfn[v], dfn[u], 1, 1, n, k);
}

int qry_path(int u, int v) {
	int ans = 0;
	while(top[u] != top[v]) {
		if(dep[top[u]] < dep[top[v]]) swap(u, v);
		ans = (ans + t.qry(dfn[top[u]], dfn[u], 1, 1, n)) % mod;
		u = fa[top[u]];
	}
	if(dep[u] < dep[v]) swap(u, v);
	ans = (ans + t.qry(dfn[v], dfn[u], 1, 1, n)) % mod;
	return ans;
} 

inline void update_subtree(int u, int k) { t.update(dfn[u], dfn[u] + siz[u] - 1, 1, 1, n, k); }

int qry_subtree(int u) { return t.qry(dfn[u], dfn[u] + siz[u] - 1, 1, 1, n); }

int main() {
	ios::sync_with_stdio(0);
	cin.tie(0), cout.tie(0);
	cin >> n >> m >> rt >> mod;
	for(int i = 1; i <= n; i++) cin >> a[i];
	int u, v;
	for(int i = 1; i < n; i++) {
		cin >> u >> v;
		G[u].push_back(v), G[v].push_back(u);
	}
	dfs1(1, 0), top[1] = 1, dfs2(1, 0);
	int opt, x, y, z;
	while(m--) {
		cin >> opt;
		if(opt == 1) cin >> x >> y >> z, update_path(x, y, z);
		if(opt == 2) cin >> x >> y, cout << qry_path(x, y) << "\n";
		if(opt == 3) cin >> x >> y, update_subtree(x, y);
		if(opt == 4) cin >> x, cout << qry_subtree(x) << "\n";
	}
	return 0;
}
2025/1/26 09:50
加载中...