rt,小样例不过,#10AC,其他WA,玄关球条,dalao们、救一下吧,眼睛都快调瞎了
#include<bits/stdc++.h>
using namespace std;
inline int read()
{
int x=0,f=1;
char ch=getchar();
while(!('0'<=ch&&ch<='9'))
{
if(ch=='-') f=-1;
ch=getchar();
}
while('0'<=ch&&ch<='9')
{
x=(x<<3)+(x<<1)+(ch^48);
ch=getchar();
}
return x*f;
}
void write(int x)
{
if(x<0)
{
putchar('-');
x=-x;
}
if(x>9) write(x/10);
putchar(x%10+'0');
}
struct node
{
int p,v;
}e[200005];
int h[100005],cnt;
void add(int u,int v)
{
e[++cnt].p=h[u];
h[u]=cnt;
e[cnt].v=v;
}
int w[100005],wt[100005],n,m,r,mod,dfscnt,son[100005],id[100005],fa[100005],dep[100005],siz[100005],top[100005];
struct nd
{
int s,lay;
}tr[400005];
void pu(int u)
{
tr[u].s=(tr[u<<1].s+tr[u<<1|1].s)%mod;
}
void pd(int u,int l,int r)
{
tr[u<<1].lay+=tr[u].lay;
tr[u<<1|1].lay+=tr[u].lay;
int mid=(l+r)>>1;
tr[u<<1].s=(tr[u<<1].s+(mid-l+1)*tr[u].lay)%mod;
tr[u<<1|1].s=(tr[u<<1].s+(r-mid)*tr[u].lay)%mod;
tr[u].lay=0;
}
void build(int u,int l,int r)
{
if(l==r)
{
tr[u].s=w[l]%mod;
return;
}
int mid=(l+r)>>1;
build(u<<1,l,mid);
build(u<<1|1,mid+1,r);
pu(u);
}
void upd(int u,int l,int r,int L,int R,int x)
{
if(L<=l&&r<=R)
{
tr[u].s=(tr[u].s+(r-l+1)*x)%mod;
tr[u].lay=(tr[u].lay+x)%mod;
return;
}
pd(u,l,r);
int mid=(l+r)>>1;
if(L<=mid) upd(u<<1,l,mid,L,R,x);
if(mid<R) upd(u<<1|1,mid+1,r,L,R,x);
pu(u);
}
int query(int u,int l,int r,int L,int R)
{
if(L<=l&&r<=R) return tr[u].s;
pd(u,l,r);
int mid=(l+r)>>1,sum=0;
if(L<=mid) sum=(sum+query(u<<1,l,mid,L,R))%mod;
if(mid<R) sum=(sum+query(u<<1|1,mid+1,r,L,R))%mod;
return sum;
}
int querysum(int x,int y)
{
int ans=0;
while(top[x]!=top[y])
{
if(dep[top[x]]<dep[top[y]]) swap(x,y);
ans=(ans+query(1,1,n,id[top[x]],id[x]))%mod;
x=fa[top[x]];
}
if(dep[x]>dep[y]) swap(x,y);
ans=(ans+query(1,1,n,id[x],id[y]))%mod;
return ans;
}
void updsum(int x,int y,int k)
{
k%=mod;
while(top[x]!=top[y])
{
if(dep[top[x]]<dep[top[y]]) swap(x,y);
upd(1,1,n,id[top[x]],id[x],k);
x=fa[top[x]];
}
if(dep[x]>dep[y]) swap(x,y);
query(1,1,n,id[x],id[y]);
}
int queryson(int x)
{
return query(1,1,n,id[x],id[x]+siz[x]-1);
}
void updson(int x,int k)
{
upd(1,1,n,id[x],id[x]+siz[x]-1,k%mod);
}
void dfs1(int u,int f,int d)
{
dep[u]=d;
fa[u]=f;
siz[u]=1;
int mxson=-1;
for(int i=h[u];i;i=e[i].p)
{
int v=e[i].v;
if(v==f) continue;
dfs1(v,u,d+1);
siz[u]=(siz[u]+siz[v])%mod;
if(siz[v]>mxson)
{
mxson=siz[v];
son[u]=v;
}
}
}
void dfs2(int u,int tp)
{
id[u]=++dfscnt;
wt[dfscnt]=w[u];
top[u]=tp;
if(!son[u]) return;
dfs2(son[u],tp);
for(int i=h[u];i;i=e[i].p)
{
int v=e[i].v;
if(v==fa[u]||v==son[u]) continue;
dfs2(v,v);
}
}
int main()
{
// freopen(".in","r",stdin);
// freopen(".out","w",stdout);
n=read(),m=read(),r=read(),mod=read();
for(int i=1;i<=n;i++)
{
w[i]=read();
}
for(int i=1;i<n;i++)
{
int u=read(),v=read();
add(u,v);
add(v,u);
}
dfs1(r,0,1);
dfs2(r,r);
build(1,1,n);
while(m--)
{
int opt=read();
if(opt==1)
{
int x=read(),y=read(),w=read();
updsum(x,y,w);
}
if(opt==2)
{
int x=read(),y=read();
write(querysum(x,y));
putchar('\n');
}
if(opt==3)
{
int x=read(),w=read();
updson(x,w);
}
if(opt==4)
{
int x=read();
write(queryson(x));
putchar('\n');
}
}
return 0;
}