28pts求调,#2,#3,#11 AC 其他全 WA
查看原帖
28pts求调,#2,#3,#11 AC 其他全 WA
752017
buowen123楼主2023/11/15 22:03
//dep, fa, siz, son, 新编号id, 新的值a,  
#include <iostream>
#define endl '\n'
using namespace std;
typedef long long ll;
const int N = 1e5 + 5;
int n, m, r, tot, head[N];
int cnt, dep[N], fa[N], siz[N], son[N], id[N], top[N];
ll p, w[N], a[N];
struct edge {
	int to, nxt;
} e[N * 2];
void add (int u, int v) {
	++tot;
	e[tot].nxt = head[u];
	e[tot].to = v;
	head[u] = tot;
}
namespace Stree {
	struct Tree {
		int l, r;
		ll val, laz;
		void update (ll v) {
			laz = (laz + v) % p;
			val = (val + (r - l + 1) * v) % p;
		}
	} tree[4 * N];
	void pushup (int t) {
		tree[t].val = (tree[t << 1].val + tree[t << 1 | 1].val) % p;
	}
	void pushdown (int t) {
		ll lazy = tree[t].laz;
		if (lazy == 0) {
			return ;
		}
		tree[t << 1].update (lazy);
		tree[t << 1 | 1].update (lazy);
		tree[t].laz = 0;
	}
	void build (int t, int l, int r) {
		tree[t].l = l;
		tree[t].r = r;
		if (l == r) {
			tree[t].val = a[l];
			return ;
		}
		int mid = l + r >> 1;
		build (t << 1, l, mid);
		build (t << 1 | 1, mid + 1, r);
		pushup (t);
	}
	void update (int t, int l, int r, ll v) {
		int ql = tree[t].l, qr = tree[t].r;
		if (l <= ql && qr <= r) {
			tree[t].update (v);
			return ;
		}
		pushdown (t);
		int mid = ql + qr >> 1;
		if (mid >= l) {
			update (t << 1, l, r, v);
		}
		if (mid < r) {
			update (t << 1 | 1, l, r, v);
		}
		pushup (t);
	}
	ll query (int t, int l, int r) {
		int ql = tree[t].l, qr = tree[t].r;
		if (l <= ql && qr <= r) {
			return tree[t].val;
		}
		pushdown (t);
		int mid = ql + qr >> 1;
		ll res = 0;
		if (mid >= l) {
			res = (res + query (t << 1, l, r)) % p;
		}
		if (mid < r) {
			res = (res + query (t << 1 | 1, l, r)) % p;
		}
		pushup (t);
		return res;
	}
}
void dfs1 (int u, int f) {
	fa[u] = f;
	dep[u] = dep[f] + 1;
	siz[u] = 1;
	int maxval = 0;
	for (int i = head[u]; i; i = e[i].nxt) {
		int v = e[i].to;
		if (v == f) {
			continue;
		}
		dfs1 (v, u);
		siz[u] += siz[v];
		if (siz[v] > maxval) {
			maxval = siz[v];
			son[u] = v;
		}
	}
}
void dfs2 (int u, int tp) {
	++cnt;
	id[u] = cnt;
	a[cnt] = w[u];
	top[u] = tp;
	if (son[u] == 0) {
		return ;
	}
	dfs2 (son[u], tp);
	for (int i = head[u]; i; i = e[i].nxt) {
		int v = e[i].to;
		if (v == fa[u] || v == son[u]) {
			continue;
		}
		dfs2 (v, v);
	}
}
void pathupd (int x, int y, ll z) {
	while (top[x] != top[y]) {
		if (dep[top[x]] < dep[top[y]]) {
			swap (x, y);
		}
		Stree::update (1, id[top[x]], id[x], z);
		x = fa[top[x]];
	}
	if (top[x] > top[y]) {
		swap (x, y);
	}
	Stree::update (1, id[x], id[y], z);
} 
ll pathque (int x, int y) {
	ll res = 0;
	while (top[x] != top[y]) {
		if (dep[top[x]] < dep[top[y]]) {
			swap (x, y);
		}
		res = (res + Stree::query (1, id[top[x]], id[x])) % p;
		x = fa[top[x]];
	}
	if (top[x] > top[y]) {
		swap (x, y);
	}
	res = (res + Stree::query (1, id[x], id[y])) % p;
	return res;
}
void treeupd (int x, ll z) {
	Stree::update (1, id[x], id[x] + siz[x] - 1, z);
}
ll treeque (int x) {
	return Stree::query (1, id[x], id[x] + siz[x] - 1);
}
int main () {
	cin >> n >> m >> r >> p;
	for (int i = 1; i <= n; ++i) {
		cin >> w[i];
	}
	for (int i = 1; i <= n - 1; ++i) {
		int u, v;
		cin >> u >> v;
		add (u, v);
		add (v, u);
	}
	dfs1 (r, 0);
	dfs2 (r, r);
	Stree::build (1, 1, n);
	for (int i = 1; i <= m; ++i) {
		int opt, x, y;
		ll z;
		cin >> opt;
		switch (opt) {
			case 1: { cin >> x >> y >> z; pathupd (x, y, z);                  break; }
			case 2: { cin >> x >> y;      cout << pathque (x, y) % p << endl; break; }
			case 3: { cin >> x >> z;      treeupd (x, z);                     break; }
			case 4: { cin >> x;           cout << treeque (x) % p << endl;    break; }
		}
	}
	return 0;
}
2023/11/15 22:03
加载中...