已经调两天了。。。求助!
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N = 400010;
int n,m,r,p;
int a[N];
int h[N],e[N],ne[N],idx,id[N],sz[N];
int bs[N],fa[N],tp[N],w[N],dep[N],tag[N],seg[N],cnt=0;
void dfs(int u,int f)
{
dep[u]=dep[f]+1;
fa[u]=f;
int mx=0,idd=0;sz[u]=1;
for(int i=h[u];i!=-1;i=ne[i])
{
if(e[i]!=f)
{
dfs(e[i],u);
sz[u]+=sz[e[i]];
if(sz[e[i]]>mx) mx=sz[e[i]],idd=e[i];
}
}
bs[u]=idd;
}
void dfs2(int u,int f,int top)
{
id[u]=++cnt;tp[u]=top;
w[cnt]=a[u];
if(bs[u])dfs2(bs[u],u,top);
for(int i=h[u];i!=-1;i=ne[i])
{
if(e[i]!=f && e[i]!=bs[u]) dfs2(e[i],u,e[i]);
}
}
void add(int a,int b){e[idx]=b,ne[idx]=h[a],h[a]=idx++;}
void build(int l,int r,int u)
{
if(l==r)
{
seg[u]=w[l];
seg[u]%=p;
return;
}
int mid=(l+r)>>1;build(l,mid,u<<1);build(mid+1,r,u<<1|1);
seg[u]=(seg[u<<1]+seg[u<<1|1])%p;
}
void pd(int u,int l,int r)
{
int mid=(l+r)>>1;
seg[u<<1]+=(mid-l+1)*tag[u]%p;seg[u<<1|1]+=(r-mid)*tag[u]%p;
tag[u<<1]+=tag[u];tag[u<<1|1]+=tag[u];tag[u]=0;
seg[u<<1]%=p;seg[u<<1|1]%=p;
}
void update(int l,int r,int ll,int rr,int u,int w)
{
if(l>=ll && r<=rr)
{
tag[u]+=w;seg[u]+=(r-l+1)*w%p;seg[u]%=p; tag[u]%=p;
pd(u,l,r);
return;
}
pd(u,l,r);int mid=(l+r)>>1;
if(mid>=ll)update(l,mid,ll,rr,u<<1,w);
if(mid<rr)update(mid+1,r,ll,rr,u<<1|1,w);
seg[u]=seg[u<<1]+seg[u<<1|1];
seg[u]%=p;
}
int query(int l,int r,int ll,int rr,int u)
{
if(l>=ll && r<=rr) return seg[u];
pd(u,l,r);
int mid=(l+r)>>1;
int ans=0;
if(mid>=ll) ans+=query(l,mid,ll,rr,u<<1);
if(mid<rr) ans+=query(mid+1,r,ll,rr,u<<1|1);
ans%=p;
return ans;
}
void updw(int x,int y,int z)
{
while(tp[x]!=tp[y])
{
if(dep[tp[x]]<dep[tp[y]]) swap(x,y);
update(1,n,id[tp[x]],id[x],1,z%p);
x=fa[tp[x]];
}
if(dep[x]>dep[y]) swap(x,y);
update(1,n,id[x],id[y],1,z);
}
void qudw(int x,int y)
{
int ans=0;
while(tp[x]!=tp[y])
{
if(dep[tp[x]]<dep[tp[y]]) swap(x,y);
ans+=query(1,n,id[tp[x]],id[x],1);
ans%=p;
x=fa[tp[x]];
}
if(dep[x]>dep[y]) swap(x,y);
ans+=query(1,n,id[x],id[y],1);
ans%=p;
printf("%lld\n",ans);
}
signed main()
{
scanf("%lld%lld%lld%lld",&n,&m,&r,&p);
for(int i=1;i<=n;i++) scanf("%lld",&a[i]);
memset(h,-1,sizeof h);
for(int i=1;i<=n-1;i++)
{
int a,b;scanf("%lld%lld",&a,&b);
add(a,b);add(b,a);
}
dfs(r,0);
dfs2(r,r,r);
build(1,n,1);
for(int i=1;i<=m;i++)
{
int op,x,y,z;
scanf("%lld",&op);
if(op==1)
{
scanf("%lld%lld%lld",&x,&y,&z);
updw(x,y,z%p);
}
else if(op==2)
{
scanf("%lld%lld",&x,&y);qudw(x,y);
}
else if(op==3)
{
scanf("%lld%lld",&x,&z);
update(1,n,id[x],id[x]+sz[x]-1,1,z%p);
}
else
{
scanf("%lld",&x);
printf("%lld\n",query(1,n,id[x],id[x]+sz[x]-1,1));
}
}
}