rt,本蒟蒻调试一个半小时,提交上去19pts,求dalao帮助
#include<iostream>
#define int long long
using namespace std;
struct Edge{
int l,nxt;
}edges[200005];
struct Tr{
int l,r,sum,laz;
}tr[800005];
int n,m,gen,mod,num[100005],tt,head[100005];
int son[100005],dep[100005],fas[100005],siz[100005];
int cnt,id[100005],val[100005],top[100005];
void add_edge(int f,int l){
tt+=1;
edges[tt]={l,head[f]};
head[f]=tt;
}
void dfs1(int x,int fa){
fas[x]=fa,siz[x]=1,dep[x]=dep[fa]+1;
for(int i=head[x];i;i=edges[i].nxt){
int l=edges[i].l;
if(l==fa) continue;
dfs1(l,x);
siz[x]+=siz[l];
if(siz[son[x]]<siz[l]) son[x]=l;
}
}
void dfs2(int x,int t){
top[x]=t,cnt+=1,id[x]=cnt,val[cnt]=num[x];
if(!son[x]) return;
dfs2(son[x],t);
for(int i=head[x];i;i=edges[i].nxt){
int l=edges[i].l;
if(l==son[x]||l==fas[x]) continue;
dfs2(l,l);
}
}
void build(int p,int l,int r){
tr[p].l=l,tr[p].r=r;
if(l==r){
tr[p].sum=val[l];
return;
}
int m=(l+r)/2;
build(p<<1,l,m);build((p<<1)+1,m+1,r);
tr[p].sum=tr[p<<1].sum+tr[(p<<1)+1].sum;
}
void pushdown(int p){
tr[p<<1].laz+=tr[p].laz;
tr[p<<1].laz%=mod;
tr[(p<<1)+1].laz+=tr[p].laz;
tr[(p<<1)+1].laz%=mod;
tr[p<<1].sum+=(tr[p<<1].r-tr[p<<1].l+1)*tr[p].laz;
tr[p<<1].sum%=mod;
tr[(p<<1)+1].sum+=(tr[(p<<1)+1].r-tr[(p<<1)+1].l+1)*tr[p].laz;
tr[(p<<1)+1].sum%=mod;
tr[p].laz=0;
}
int Find(int p,int l,int r){
pushdown(p);
if(l<=tr[p].l&&tr[p].r<=r) return tr[p].sum;
int m=(tr[p].l+tr[p].r)/2,ok=0;
if(l<=m) ok+=Find(p<<1,l,r);
ok%=mod;
if(m<r) ok+=Find((p<<1)+1,l,r);
ok%=mod;
return ok;
}
int Find_tr(int x,int y){
int ok=0;
while(top[x]!=top[y]){
if(dep[top[x]]<dep[top[y]]) swap(x,y);
ok+=Find(1,id[top[x]],id[x]);
ok%=mod;
x=fas[top[x]];
}
if(dep[x]<dep[y]) swap(x,y);
ok+=Find(1,id[y],id[x]);
ok%=mod;
return ok;
}
int Find_son(int x){
return Find(1,id[x],id[x]+siz[x]-1);
}
void update(int l,int r,int p,int k){
if(l<=tr[p].l&&tr[p].r<=r){
tr[p].laz+=k;
tr[p].laz%=mod;
tr[p].sum+=k*(tr[p].r-tr[p].l+1);
tr[p].sum%=mod;
return;
}
pushdown(p);
int m=(tr[p].l+tr[p].r)/2;
if(l<=m) update(l,r,p<<1,k);
if(m<r) update(l,r,(p<<1)+1,k);
}
void update_tr(int x,int y,int k){
while(top[x]!=top[y]){
if(dep[top[x]]<dep[top[y]]) swap(x,y);
update(id[top[x]],id[x],1,k);
x=fas[top[x]];
}
if(dep[x]<dep[y]) swap(x,y);
update(id[y],id[x],1,k);
}
void update_son(int x,int k){
update(id[x],id[x]+siz[x]-1,1,k);
}
signed main(){
int f,l;
cin>>n>>m>>gen>>mod;
for(int i=1;i<=n;i++) cin>>num[i];
for(int i=1;i<n;i++){
cin>>f>>l;
add_edge(f,l);
add_edge(l,f);
}
int op,x,y,z;
dfs1(gen,0);dfs2(gen,gen);
build(1,1,n);
while(m--){
cin>>op;
if(op==1){
cin>>x>>y>>z;
update_tr(x,y,z);
}
else if(op==2){
cin>>x>>y;
cout<<Find_tr(x,y)%mod<<endl;
}
else if(op==3){
cin>>x>>z;
update_son(x,z);
}
else{
cin>>x;
cout<<Find_son(x)%mod<<endl;
}
}
return 0;
}