MnZn WA30pts求调
查看原帖
MnZn WA30pts求调
362101
_TLEer_的小号楼主2021/8/3 18:44

Rt.照着第一篇写的

code:

#include <iostream>
#include <cstdio>
#include <cctype>
#define int long long
#define il inline
#define N 100010
#define re register
using namespace std;
int MOD, root;
inline int read()
{
	char c;
	int t = 1, ans;
	while (!isdigit(c = getchar()))
		if (c == '-')
			t = -t;
	ans = c - '0';
	while (isdigit(c = getchar()))
		ans = ans * 10 + c - '0';
	return ans;
}
struct ln
{
	int u, v, nxt;
} a[N * 5];
int n, m, p, x, y, z, k, hd[N], ar[N], tmp, op, lnsz, dep[N], f[N], tr[N], son[N], arr[N], nw[N], t[N], tot;
struct Segment_Tree
{
	int L[N * 10], R[N * 10], lazy_tag[N * 10], tag[N * 10], ans[N * 10], lson[N * 10], rson[N * 10];
	il void pushdown(int i)
	{
		lazy_tag[lson[i]] += lazy_tag[i];
		ans[lson[i]] += lazy_tag[i] * (R[lson[i]] - L[lson[i]] + 1);
		lazy_tag[rson[i]] += lazy_tag[i];
		ans[rson[i]] += lazy_tag[i] * (R[rson[i]] - L[rson[i]] + 1);
		lazy_tag[i] = 0;
	}
	il void pushup(int i)
	{
		ans[i] = ans[rson[i]] + ans[lson[i]];
	}
	il void add(int i, int l, int r, int c)
	{
		if (l == L[i] && R[i] == r)
		{
			if (l != r)
				lazy_tag[i] += c;
			ans[i] += c * (R[i] - L[i] + 1);
			return;
		}
		if (r <= R[lson[i]])
			add(lson[i], l, r, c);
		else if (l >= L[rson[i]])
			add(rson[i], l, r, c);
		else
			add(rson[i], L[rson[i]], r, c), add(lson[i], l, R[lson[i]], c);
		pushdown(i);
		pushup(i);
	}
	il int ask(int i, int l, int r)
	{
		if (l == L[i] && R[i] == r)
			return ans[i];
		if (lazy_tag[i])
			pushdown(i);
		if (r <= R[lson[i]])
			return ask(lson[i], l, r);
		if (l >= L[rson[i]])
			return ask(rson[i], l, r);
		return ask(rson[i], L[rson[i]], r) + ask(lson[i], l, R[lson[i]]);
	}
	il void make_tree(int i, int l, int r)
	{
		tag[i] = i;
		L[i] = l;
		R[i] = r;
		lson[i] = tag[i] * 2;
		rson[i] = lson[i] + 1;
		if (l == r)
			return;
		make_tree(i * 2, l, l + ((r - l) >> 1));
		make_tree(i * 2 + 1, ((r - l) >> 1) + 1 + l, r);
	}
} T;
void merge(int u, int v)
{
	a[++lnsz].u = u;
	a[lnsz].v = v;
	a[lnsz].nxt = hd[u];
	hd[u] = lnsz;
}
void dfs1(int u, int d, int fa)
{
	int tmp = -1;
	dep[u] = d;
	f[u] = fa;
	tr[u] = 1;
	for (re int i = hd[u]; i; i = a[i].nxt)
	{
		if (a[i].v == fa)
			continue;
		dfs1(a[i].v, d + 1, u);
		tr[u] += tr[a[i].v];
		if (tr[a[i].v] > tmp)
			tmp = tr[a[i].v], son[u] = a[i].v;
	}
}
il void dfs2(int u, int tp, int fa)
{
	t[u] = tp;
	nw[u] = ++tot;
	arr[tot] = ar[u];
	if (!son[u])
		return;
	dfs2(son[u], tp, u);
	for (re int i = hd[u]; i; i = a[i].nxt)
		if (a[i].v != fa && a[i].v != son[u])
			dfs2(a[i].v, a[i].v, u);
}
void dfs_add(int x, int y, int c)
{
	while (t[x] != t[y])
	{
		if (dep[t[x]] < dep[t[y]])
			swap(x, y);
		T.add(1, nw[t[x]], nw[x], c);
		x = f[t[x]];
	}
	if (dep[x] > dep[y])
		swap(x, y);
	T.add(1, nw[x], nw[y], c);
}
il int dfs_ask(int x, int y)
{
	int ans = 0;
	while (t[x] != t[y])
	{
		if (dep[t[x]] < dep[t[y]])
			swap(x, y);
		ans += T.ask(1, nw[t[x]], nw[x]);
		ans %= MOD;
		x = f[t[x]];
	}
	if (dep[x] > dep[y])
		swap(x, y);
	return (ans + T.ask(1, nw[x], nw[y])) % MOD;
}

signed main()
{
	n = read();
	m = read();
	root = read();
	MOD = read();
	T.make_tree(1, 1, n);
	for (re int i = 1; i <= n; i++)
		cin >> ar[i];
	for (re int i = 1; i < n; i++)
	{
		x = read();
		y = read();
		merge(x, y);
		merge(y, x);
	}
	dfs1(root, 1, 0);
	dfs2(root, root, 0);
	for (re int i = 1; i <= n; i++)
		T.add(1, i, i, arr[i]);
	for (re int i = 0; i < m; i++)
	{
		op = read();
		x = read();
		if (op == 1)
		{
			y = read();
			z = read();
			dfs_add(x, y, z);
		}
		else if (op == 4)
			cout << T.ask(1, nw[x], nw[x] + tr[x] - 1) << endl;
		else if (op == 3)
			y = read(), T.add(1, nw[x], nw[x] + tr[x] - 1, y);
		else
			y = read(), cout << dfs_ask(x, y) << endl;
	}
	return 0;
}
2021/8/3 18:44
加载中...