```cpp
#include<bits/stdc++.h>
using namespace std;
#define int long long
int n, m, r, p, a[100005];
int depth[100005], size[100005], son[100005], fa[100005], dfn[100005], top[100005], curdfn, lx[100005], rx[100005];
struct node{
int l, r, sum, lazy;
}f[400005];
vector<int> g[100005];
void dfs1(int x, int father, int dep){
depth[x] = dep, size[x] = 1, fa[x] = father;
int maxson = 0, maxs = 0;
for(int i = 0;i < g[x].size();i++){
int k = g[x][i];
if(k == father)
continue;
dfs1(k, x, dep + 1);
size[x] += size[k];
if(size[k] > maxson)
maxson = size[i], maxs = k;
}
son[x] = maxs;
}
void dfs2(int x, int cl){
dfn[x] = ++curdfn, top[x] = cl;
if(g[x].size() > 1 || x == r)
dfs2(son[x], cl);
for(int i = 0;i < g[x].size();i++){
int k = g[x][i];
if(dfn[k])
continue;
dfs2(k, k);
}
lx[x] = dfn[x], rx[x] = curdfn;
}
void pushup(int id){
f[id].sum = (f[id * 2 + 1].sum + f[id * 2].sum) % p;
}
void pushdown(int id){
f[id * 2].sum = (f[id * 2].sum + f[id].lazy * (f[id * 2].r - f[id * 2].l + 1)) % p;
f[id * 2 + 1].sum = (f[id * 2 + 1].sum + f[id].lazy * (f[id * 2 + 1].r - f[id * 2 + 1].l + 1)) % p;
f[id * 2].lazy += f[id].lazy, f[id * 2].lazy %= p;
f[id * 2 + 1].lazy += f[id].lazy, f[id * 2 + 1].lazy %= p;
f[id].lazy = 0;
}
void build(int l, int r, int id){
f[id].l = l, f[id].r = r;
if(l == r)
return;
int mid = (l + r) / 2;
build(l, mid, id * 2);
build(mid + 1, r, id * 2 + 1);
pushup(id);
}
void modify(int l, int r, int k, int id){
if(f[id].l == l && f[id].r == r){
f[id].lazy += k, f[id].lazy %= p;
f[id].sum += k * (r - l + 1), f[id].sum %= p;
return;
}
pushdown(id);
if(r <= f[id * 2].r)
modify(l, r, k, id * 2);
else
if(l >= f[id * 2 + 1].l)
modify(l, r, k, id * 2 + 1);
else
modify(l, f[id * 2].r, k, id * 2), modify(f[id * 2 + 1].l, r, k, id * 2 + 1);
pushup(id);
}
int query(int l, int r, int id){
if(l == f[id].l && r == f[id].r)
return f[id].sum;
pushdown(id);
if(r <= f[id * 2].r)
return query(l, r, id * 2) % p;
else
if(l >= f[id * 2 + 1].l)
return query(l, r, id * 2 + 1) % p;
else
return (query(l, f[id * 2].r, id * 2) + query(f[id * 2 + 1].l, r, id * 2 + 1)) % p;
pushup(id);
}
signed main(){
cin>>n>>m>>r>>p;
for(int i = 1;i <= n;i++)
cin>>a[i];
for(int i = 1;i < n;i++){
int u, v;
cin>>u>>v;
g[u].push_back(v);
g[v].push_back(u);
}
dfs1(r, 0, 0);
dfs2(r, r);
build(1, n, 1);
for(int i = 1;i <= n;i++)
modify(dfn[i], dfn[i], a[i], 1);
/*for(int i = 1;i <= n;i++)
cout<<lx[i]<<' '<<rx[i]<<' '<<son[i]<<' '<<fa[i]<<' '<<size[i]<<' '<<top[i]<<' '<<dfn[i]<<endl;*/
while(m--){
int op;
cin>>op;
if(op == 1){
int x, y, z;
scanf("%lld %lld %lld", &x, &y, &z);
int u = x, v = y;
/*for(int i = 1;i <= n;i++)
cout<<query(i, i, 1)<<' ';
cout<<endl;*/
while(top[u] != top[v]){
if(depth[top[u]] < depth[top[v]])
swap(u, v);
modify(dfn[top[u]], dfn[u], z, 1);
u = fa[top[u]];
}
if(depth[u] > depth[v])
swap(u, v);
/*for(int i = 1;i <= n;i++)
cout<<query(i, i, 1)<<' ';
cout<<endl;*/
modify(dfn[u], dfn[v], z, 1);
/*cout<<dfn[u]<<' '<<dfn[v]<<endl;*/
/*for(int i = 1;i <= n;i++)
cout<<query(i, i, 1)<<' ';
cout<<endl;*/
}
if(op == 2){
int x, y;
scanf("%lld %lld", &x, &y);
int u = x, v = y, ans = 0;
while(top[u] != top[v]){
if(depth[top[u]] < depth[top[v]])
swap(u, v);
ans += query(dfn[top[u]], dfn[u], 1);
ans %= p;
u = fa[top[u]];
/*cout<<u<<' '<<v<<endl;*/
}
if(depth[u] > depth[v])
swap(u, v);
ans += query(dfn[u], dfn[v], 1);
cout<<ans % p<<endl;
}
if(op == 3){
int x, z;
scanf("%lld %lld", &x, &z);
modify(lx[x], rx[x], z, 1);
/*for(int i = 1;i <= n;i++)
cout<<query(i, i, 1)<<' ';
cout<<endl;*/
}
if(op == 4){
int x;
scanf("%lld", &x);
cout<<query(lx[x], rx[x], 1)<<endl;
}
}
return 0;
}
```
by _OJF_ @ 2021-12-18 14:13:45
op=2 没取模
by esquigybcu @ 2021-12-19 12:47:48