求帮助QAQ~~
#include<cstdio>
#include<cstring>
#include<algorithm>
#define N 100005<<2
#define M 200005
#define ll long long
using namespace std;
int n,m,root,op,rk[N];
ll P,_sum,k,a[N];
int lx,ly,cnt,tot;
struct Tree
{
int L[N],R[N];
ll add[N],sum[N];
void build(int o,int l,int r)
{
int lc=o*2,rc=o*2+1,mid=l+(r-l)/2;
L[o]=l;R[o]=r;
if(l==r){sum[o]=a[rk[l]];return ;}
build(lc,l,mid);
build(rc,mid+1,r);
sum[o]=(sum[lc]+sum[rc])%P;
}
void spread(int o)
{
int lc=o*2,rc=o*2+1;
sum[lc]+=add[o]*(ll)(R[lc]-L[lc]+1);
sum[rc]+=add[o]*(ll)(R[rc]-L[rc]+1);
add[lc]+=add[o];
add[rc]+=add[o];
add[o]=0LL;
sum[lc]%=P;
sum[rc]%=P;
add[lc]%=P;
add[rc]%=P;
}
void update(int o)
{
int l=L[o],r=R[o];
int mid=l+(r-l)/2;
if (lx<=l&&r<=ly)
{
add[o]+=k;
add[o]%=P;
sum[o]+=k*(ll)(r-l+1);
}
else
{
spread(o);
if (lx<=mid)update(o*2);
if (ly>mid)update(o*2+1);
sum[o]=sum[l]+sum[r];
sum[o]%=P;
}
}
void ask(int o)
{
int lc=o*2,rc=o*2+1,l=L[o],r=R[o];
int mid=l+(r-l)/2;
if (lx<=l&&r<=ly)
{
_sum+=sum[o];
_sum%=P;
}
else
{
spread(o);
if (lx<=mid)ask(lc);
if (ly>mid)ask(rc);
}
}
}tree;
struct edges{
int to;
int nxt;
}edge[M];
int head[M];
void add(int x,int y)
{
edge[++tot].nxt=head[x];
edge[tot].to=y;
head[x]=tot;
}
int size[N],fa[N],son[N],deep[N];
bool vis[N];
void dfs1(int u,int f,int d)
{
vis[u]=true;
fa[u]=f;
deep[u]=d+1;
size[u]=1;
for (int i=head[u];i;i=edge[i].nxt)
{
int v=edge[i].to;
if (vis[v])continue;
dfs1(v,u,d+1);
size[u]+=size[v];
if (size[v]>size[son[u]])
son[u]=v;
}
}
int top[N],id[N],last[N];
void dfs2(int u,int t)
{
vis[u]=true;
top[u]=t;
id[u]=++cnt;
rk[cnt]=u;
last[u]=id[u]+size[u]-1;
if (son[u])dfs2(son[u],t);
for (int i=head[u];i;i=edge[i].nxt)
{
int v=edge[i].to;
if (vis[v])continue;
dfs2(v,v);
}
}
inline void control()
{
if (op==1)
{
tree.update(1);
}
if (op==2)
{
tree.ask(1);
}
}
void lca(int x,int y)
{
while(top[x]!=top[y])
{
if (deep[top[x]]<deep[top[y]])swap(x,y);
lx=id[top[x]];
ly=id[x];
control();
x=fa[top[x]];
}
lx=id[x],ly=id[y];
if (deep[x]>deep[y])swap(lx,ly);
control();
}
int main()
{
scanf("%d%d%d%lld",&n,&m,&root,&P);
for (int i=1;i<=n;i++)
{
scanf("%lld",&a[i]);
}
for (int i=1;i<n;i++)
{
int x,y;
scanf("%d%d",&x,&y);
add(x,y);
add(y,x);
}
memset(vis,0,sizeof(vis));
dfs1(root,0,0);
memset(vis,0,sizeof(vis));
dfs2(root,root);
tree.build(1,1,n);
for (int i=1;i<=m;i++)
{
int x,y;
scanf("%d",&op);
if (op==1)
{
scanf("%d%d%lld",&x,&y,&k);
lca(x,y);
}
if (op==2)
{
scanf("%d%d",&x,&y);
_sum=0LL;
lca(x,y);
printf("%lld\n",_sum);
}
if (op==3)
{
scanf("%d%lld",&x,&k);
lx=id[x];
ly=last[x];
tree.update(1);
}
if (op==4)
{
scanf("%d",&x);
lx=id[x];
ly=last[x];
_sum=0LL;
tree.ask(1);
printf("%lld\n",_sum);
}
}
}