#include <cstdio>
#include <iostream>
#include <cmath>
#include <algorithm>
#include <string>
#include <cstring>
#include <queue>
#include <map>
using namespace std;
typedef long long ll;
int n,m,s,mod;
int nxt[200005],hed[100005],to[100005],a[100005];
int cnt=0;
int c[4][100005];
void adde(int u,int v)
{
cnt++;
to[cnt]=v;
nxt[cnt]=hed[u];
hed[u]=cnt;
}
int lowbit(int x) {return x&-x;}
void upd(int x,int kin,int k)
{
while(x<=n)
{
c[kin][x]=(c[kin][x]+k+5*mod)%mod;
x+=lowbit(x);
}
}
int query(int kin,int x)
{
int res=0;
while(x>=1)
{
res=(c[kin][x]+res+mod*5)%mod;
x-=lowbit(x);
}
return (res+5*mod)%mod;
}
void update(int x,int y,int z)
{
z%=mod;
upd(x,1,z);
upd(x,2,(z*x)%mod);
upd(y+1,1,-z);
upd(y+1,2,-(z*(y+1)%mod));
}
int ask(int x,int y)
{
return (((y+1)*query(1,y)%mod-query(2,y))-(x*query(1,x-1)%mod-query(2,x-1))+5*mod)%mod;
}
//BIT 结束
int dfscnt;
int f[100005],dth[100005],siz[100005],id[100005],son[100005],top[100005],rk[100005];
void dfs1(int u,int fa,int dep)
{
f[u]=fa;
dth[u]=dep;
siz[u]=1;
for(int i=hed[u];i!=0;i=nxt[i])
{
int v=to[i];
if(v==f[u]) continue;
dfs1(v,u,dep+1);
siz[u]+=siz[v];
if(siz[v]>siz[son[u]]) son[u]=v;
}
}
void dfs2(int u,int tp)
{
dfscnt++;
id[u]=dfscnt;
rk[dfscnt]=u;
top[u]=tp;
if(son[u]!=0) dfs2(son[u],tp);
for(int i=hed[u];i!=0;i=nxt[i])
{
int v=to[i];
if(v!=son[u]&&v!=f[u])
{
dfs2(v,v);
}
}
}
int main()
{
cin>>n>>m>>s>>mod;
for(int i=1;i<=n;i++)
{
cin>>a[i];
}
for(int i=1;i<n;i++)
{
int u,v;
cin>>u>>v;
adde(u,v);
adde(v,u);
}
dfs1(s,0,1);
dfs2(s,s);
for(int i=1;i<=n;i++)
{
update(id[i],id[i],a[i]);
}
for(int i=1;i<=m;i++)
{
int opt;
cin>>opt;
if(opt==3)
{
int x,z;
cin>>x>>z;
update(id[x],id[x]+siz[x]-1,z);
}
if(opt==4)
{
int x;
cin>>x;
cout<<ask(id[x],id[x]+siz[x]-1)<<endl;
}
if(opt==1)
{
int x,y,z;
cin>>x>>y>>z;
int fx=top[x],fy=top[y];
while(fx!=fy)
{
if(dth[fx]>=dth[fy])
{
update(id[fx],id[x],z);
x=f[fx];
fx=top[x];
}
else
{
update(id[fy],id[y],z);
y=f[fy];
fy=top[y];
}
}
if(id[x]<=id[y])
{
update(id[x],id[y],z);
}
else
{
update(id[y],id[x],z);
}
}
if(opt==2)
{
int ans=0,x,y;
cin>>x>>y;
int fx=top[x],fy=top[y];
while(fx!=fy)
{
if(dth[fx]>=dth[fy])
{
ans=(ans+ask(id[fx],id[x]))%mod;
x=f[fx];
fx=top[x];
}
else
{
ans=(ans+ask(id[fy],id[y]))%mod;
y=f[fy];
fy=top[y];
}
}
if(id[x]>=id[y]) ans=(ans+ask(id[y],id[x]))%mod;
else ans=(ans+ask(id[x],id[y]))%mod;
cout<<ans%mod<<endl;
}
}
return 0;
}
WA了2 9 10,貌似是三个数据比较大的点,怀疑是爆int了或者取模爆炸了,求大佬们康康qaq
区间加区间求和是用的树状数组,应该没写错(吧