除第四个点外全WA
#include<bits/stdc++.h>
using namespace std;typedef long long ll;
const ll MAX=1e5+5;
ll n,T,R,MOD,a[MAX],tot,edge[MAX<<1],nxt[MAX<<1],head[MAX],x,y,z,fa[MAX],dep[MAX],zson[MAX],dfss[MAX],cnt,zs[MAX],zld[MAX],xds[MAX<<2],tagg[MAX<<2],opt,xbh[MAX],ans;
void add(ll x,ll y){
edge[++tot]=y,nxt[tot]=head[x],head[x]=tot;
edge[++tot]=x,nxt[tot]=head[y],head[y]=tot;
return;
}
void dfs1(ll x,ll dadd){
fa[x]=dadd;dep[x]=dep[dadd]+1;zs[x]=1;
for(int i=head[x];i!=0;i=nxt[i])
if(edge[i]!=dadd){
dfs1(edge[i],x);
zs[x]+=zs[edge[i]];
if(zs[edge[i]]>zs[zson[x]])zson[x]=edge[i];
}
return;
}
void dfs2(ll x){
if(zld[x]==0)zld[x]=x;
dfss[++cnt]=x;xbh[x]=cnt;
if(zson[x]!=0)zld[zson[x]]=zld[x],dfs2(zson[x]);
for(int i=head[x];i!=0;i=nxt[i])
if(edge[i]!=fa[x]&&edge[i]!=zson[x])dfs2(edge[i]);
return;
}
void build(ll l,ll r,ll wz){
if(l>r)return;
if(l==r){xds[wz]=a[dfss[l]];return;}
ll mid=((l+r)>>1);
build(l,mid,wz<<1);build(mid+1,r,wz<<1|1);xds[wz]=xds[wz<<1]+xds[wz<<1|1];
return;
}
void change(ll l,ll r,ll la,ll ra,ll wz,ll x){
ll mid=(l+r)>>1;
if(l>=la&&r<=ra){tagg[wz]=(tagg[wz]+x)%MOD;xds[wz]=(xds[wz]+(ra-la+1)*x%MOD)%MOD;return;}
if(tagg[wz]!=0)tagg[wz<<1]=(tagg[wz]+tagg[wz<<1])%MOD,tagg[wz<<1|1]=(tagg[wz<<1|1]+tagg[wz])%MOD,xds[wz<<1]=(xds[wz<<1]+(mid-l+1)*tagg[wz])%MOD,xds[wz<<1|1]=(xds[wz<<1|1]+(r-mid)*tagg[wz])%MOD,tagg[wz]=0;
if(mid>=la)change(l,mid,la,ra,wz<<1,x);
if(mid<ra)change(mid+1,r,la,ra,wz<<1|1,x);
xds[wz]=(xds[wz<<1]+xds[wz<<1|1])%MOD;
return;
}
ll cx(ll l,ll r,ll la,ll ra,ll wz){
if(l>=la&&r<=ra)return xds[wz];
ll mid=(l+r)>>1,ans=0;
if(tagg[wz]!=0)tagg[wz<<1]=(tagg[wz<<1]+tagg[wz])%MOD,tagg[wz<<1|1]=(tagg[wz<<1|1]+tagg[wz])%MOD,xds[wz<<1]=(xds[wz<<1]+(mid-l+1)*tagg[wz])%MOD,xds[wz<<1|1]=(xds[wz<<1|1]+(r-mid)*tagg[wz])%MOD,tagg[wz]=0;
if(mid>=la)ans=cx(l,mid,la,ra,wz<<1);
if(mid<ra)ans+=cx(mid+1,r,la,ra,wz<<1|1);
return ans%MOD;
}
int main(){
scanf("%lld%lld%lld%lld",&n,&T,&R,&MOD);
for(int i=1;i<=n;i++)scanf("%lld",&a[i]),a[i]%=MOD;
for(int i=1;i<n;i++)scanf("%lld%lld",&x,&y),add(x,y);
dfs1(R,0);dfs2(R);build(1,n,1);
while(T--){
scanf("%lld%lld",&opt,&x);
switch(opt){
case 1:{
scanf("%lld%lld",&y,&z);
while(zld[x]!=zld[y]){
if(dep[zld[x]]<dep[zld[y]])swap(x,y);
change(1,n,xbh[zld[x]],xbh[x],1,z);
x=fa[zld[x]];
}
if(xbh[x]>xbh[y])swap(x,y);
change(1,n,xbh[x],xbh[y],1,z);
break;
}
case 2:{
scanf("%lld",&y);
ans=0;
while(zld[x]!=zld[y]){
if(dep[zld[x]]<dep[zld[y]])swap(x,y);
ans=(ans+cx(1,n,xbh[zld[x]],xbh[x],1))%MOD;
x=fa[zld[x]];
}
if(xbh[x]>xbh[y])swap(x,y);
printf("%lld\n",(ans+cx(1,n,xbh[x],xbh[y],1))%MOD);
break;
}
case 3:{scanf("%lld",&z);change(1,n,xbh[x],xbh[x]+zs[x]-1,1,z);break;}
case 4:{printf("%lld\n",cx(1,n,xbh[x],xbh[x]+zs[x]-1,1));break;}
}
}
return 0;
}