玄关
这个帖子里的常见错误好像都没犯
奇怪了
#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;
}