37pts 求助
查看原帖
37pts 求助
487383
imnoob楼主2025/2/2 20:55

玄关

这个帖子里的常见错误好像都没犯

奇怪了

#include <bits/stdc++.h>
#define Code using
#define by namespace
#define zzx std
Code by zzx;
int n, m, r;
vector<int> e[200010];
int dep[200010], sz[200010], son[200010], fa[200010];
int id[200010], top[200010], cnt = 0;
long long mod, a[200010], w[200010];
long long d[1200010], tag[1200010];

//线段树 

void build(int s, int t, int p)
{
	if(s == t)
	{
		d[p] = w[s];
		return;
	}
	int mid = (s + t) / 2;
	build(s, mid, p * 2);
	build(mid + 1, t, p * 2 + 1);
	d[p] = (d[p * 2] + d[p * 2 + 1]) % mod;
}

void pushdown(int s, int t, int p)
{
	if(s == t || !tag[p])
	{
		return;
	}
	int mid = (s + t) / 2;
	d[p * 2] += tag[p] * (long long)(mid - s + 1);
	d[p * 2 + 1] += tag[p] * (long long)(t - mid);
	tag[p * 2] += tag[p];
	tag[p * 2 + 1] += tag[p];
	tag[p] = 0;
}

void update(int l, int r, int s, int t, long long x, int p)
{
	if(l <= s && t <= r)
	{
		d[p] += (long long)(t - s + 1) * x;
		tag[p] += x;
		return; 
	}
	int mid = (s + t) / 2;
	pushdown(s, t, p);
	if(l <= mid)
	{
		update(l, r, s, mid, x, p * 2);
	}
	if(mid < r)
	{
		update(l, r, mid + 1, t, x, p * 2 + 1);
	}
	d[p] = d[p * 2] + d[p * 2 + 1];
}

long long getsum(int l, int r, int s, int t, int p)
{
	if(l <= s && t <= r)
	{
		return d[p];
	}
	int mid = (s + t) / 2;
	pushdown(s, t, p);
	long long res = 0;
	if(l <= mid)
	{
		res += getsum(l, r, s, mid, p * 2);
	}
	if(mid < r)
	{
		res += getsum(l, r, mid + 1, t, p * 2 + 1); 
	}
	d[p] = d[p * 2] + d[p * 2 + 1];
	return res;
}

//线段树 

void dfs1(int l, int u)
{
	fa[u] = l;
	dep[u] = dep[l] + 1;
	sz[u] = 1;
	int maxs = 0;
	for(int i = 0; i < e[u].size(); ++i)
	{
		int v = e[u][i];
		if(v == l)
		{
			continue;
		}
		dfs1(u, v);
		sz[u] += sz[v];
		if(maxs < sz[v])
		{
			son[u] = v;
			maxs = sz[v];
		}
	}
}

void dfs2(int u, int topf)
{
	id[u] = ++cnt;
	w[cnt] = a[u];
	top[u] = topf;
	if(sz[u] == 1)
	{
		return;
	}
	dfs2(son[u], topf);
	for(int i = 0; i < e[u].size(); ++i)
	{
		int v = e[u][i];
		if(v == fa[u] || v == son[u])
		{
			continue;
		} 
		dfs2(v, v);
	}
}

void query1(int x, int y, long long z)
{
	while(top[x] != top[y])
	{
		if(dep[top[x]] < dep[top[y]])
		{
			swap(x, y);
		}
		update(id[top[x]], id[x], 1, n, z, 1);
		x = fa[top[x]];
	}
	if(dep[x] > dep[y])
	{
		swap(x, y);
	}
	update(id[x], id[y], 1, n, z, 1);
}

long long query2(int x, int y)
{
	long long res = 0;
	while(top[x] != top[y])
	{
		if(dep[top[x]] < dep[top[y]])
		{
			swap(x, y);
		}
		res = (res + getsum(id[top[x]], id[x], 1, n, 1)) % mod;
		x = fa[top[x]];
	}
	if(dep[x] > dep[y])
	{
		swap(x, y);
	}
	res = (res + getsum(id[x], id[y], 1, n, 1)) % mod;
	return res;
}

void query3(int x, long long z)
{
	update(id[x], id[x] + sz[x] - 1, 1, n, z, 1);
}

long long query4(int x)
{
	return getsum(id[x], id[x] + sz[x] - 1, 1, n, 1);
}

int main()
{
	cin >> n >> m >> r >> mod;
	for(int i = 1; i <= n; ++i)
	{
		cin >> a[i];
		a[i] %= mod;
	}
	for(int i = 1; i < n; ++i)
	{
		int u, v;
		cin >> u >> v;
		e[u].push_back(v);
		e[v].push_back(u);
	}
	dfs1(0, r);
	dfs2(r, r);
	build(1, n, 1);
	for(int i = 1; i <= m; ++i)
	{
		int type, x, y;
		long long z;
		cin >> type; // 操作编号 
		if(type == 1)
		{
			cin >> x >> y >> z;	
			query1(x, y, z);
		}
		else if(type == 2)
		{
			cin >> x >> y;
			cout << query2(x, y) << '\n';
		}
		else if(type == 3)
		{
			cin >> x >> z;
			query3(x, z);
		}
		else
		{
			cin >> x;
			cout << query4(x) << '\n';
		}
	}
	return 0;
}
2025/2/2 20:55
加载中...