不知道错哪里了,调了很久
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll N=2e5+5;
struct path{
ll u,v,nxt;
}e[N*2];
int head[N];
int num;
inline void addpath(int x,int y){
e[++num].u=x;
e[num].v=y;
e[num].nxt=head[x];
head[x]=num;
return ;
}
int deep[N];
int fa[N];
int son[N];
int tot[N];
int top[N];
int idx[N];
int n,m,r,mod,cnt,a[N],b[N];
int op,xx,yy,k;
inline int dfs1(int now,int f,int dep){
deep[now]=dep;
fa[now]=f;
tot[now]=1;
int maxson=-1;
for(int i=head[now];i!=-1;i=e[i].nxt){
if(e[i].v==f)
continue;
tot[now]+=dfs1(e[i].v,now,dep+1);
if(tot[e[i].v]>maxson)
maxson=tot[e[i].v],son[now]=e[i].v;
}
return tot[now];
}
inline void dfs2(int now,int topf){
idx[now]=++cnt;
a[cnt]=b[now];
top[now]=topf;
if(!son[now])
return ;
dfs2(son[now],topf);
for(int i=head[now];i!=-1;i=e[i].nxt)
if(!idx[e[i].v])
dfs2(e[i].v,e[i].v);
return ;
}
struct node{
int l,r;
int tag;
int sum;
}tree[N*4];
inline void build(int i,int l,int r){
tree[i].l=l;
tree[i].r=r;
if(l==r){
tree[i].sum=a[l];
return ;
}
int mid=(l+r)>>1;
build(i*2,l,mid);
build(i*2+1,mid+1,r);
tree[i].sum=tree[i*2].sum+tree[i*2+1].sum;
tree[i].sum%=mod;
return ;
}
inline void pushdown(int i){
if(tree[i].tag!=0){
tree[i*2].tag+=tree[i].tag;
tree[i*2+1].tag+=tree[i].tag;
int mid=(tree[i].l+tree[i].r)>>1;
tree[i*2].sum+=tree[i].tag*(mid-tree[i].l+1);
tree[i*2+1].sum+=tree[i].tag*(tree[i].r-mid);
tree[i].tag=0;
}
return ;
}
inline void add(int i,int l,int r,int k){
if(tree[i].l>=l&&tree[i].r<=r){
tree[i].sum+=k*(tree[i].r-tree[i].l+1);
tree[i].tag+=k;
return ;
}
pushdown(i);
if(tree[i*2].r>=l)
add(i*2,l,r,k);
if(tree[i*2+1].l<=r)
add(i*2+1,l,r,k);
tree[i].sum=tree[i*2].sum+tree[i*2+1].sum;
tree[i].sum%=mod;
return ;
}
inline int search(int i,int l,int r){
if(tree[i].l>=l&&tree[i].r<=r)
return tree[i].sum;
if(tree[i].l>r||tree[i].r<l)
return 0;
int ans=0;
if(tree[i*2].r>=l)
ans+=search(i*2,l,r);
if(tree[i*2+1].l<=r)
ans+=search(i*2,l,r);
ans%=mod;
return ans;
}
inline void treeadd(int x,int y,int val){
while(top[x]!=top[y]){
if(deep[top[x]]<deep[top[y]])
swap(x,y);
add(1,idx[top[x]],idx[x],val);
x=fa[top[x]];
}
if(deep[x]>deep[y])
swap(x,y);
add(1,idx[x],idx[y],val);
}
inline void treesum(int x,int y){
int ans=0;
while(top[x]!=top[y]){
if(deep[top[x]]<deep[top[y]])
swap(x,y);
ans+=search(1,idx[top[x]],idx[x]);
ans%=mod;
x=fa[top[x]];
}
if(deep[x]>deep[y])
swap(x,y);
ans+=search(1,idx[x],idx[y]);
ans%=mod;
printf("%d\n",ans);
return ;
}
inline void sonadd(ll x,ll val){
add(1,idx[x],idx[x]+tot[x]-1,val);
return ;
}
inline void sonsum(int x){
printf("%d\n",search(1,idx[x],idx[x]+tot[x]-1)%mod);
return ;
}
int main(){
memset(head,-1,sizeof(head));
scanf("%d%d%d%d",&n,&m,&r,&mod);
for(int i=1;i<=n;i++)
scanf("%d",&b[i]);
for(int i=1;i<n;i++){
ll x,y;
scanf("%d%d",&x,&y);
addpath(x,y);
addpath(y,x);
}
dfs1(r,0,1);
dfs2(r,r);
build(1,1,n);
while(m--){
scanf("%d",&op);
if(op==1){
scanf("%d%d%d",&xx,&yy,&k);
treeadd(xx,yy,k%mod);
}
if(op==2){
scanf("%d%d",&xx,&yy);
treesum(xx,yy);
}
if(op==3){
scanf("%d%d",&xx,&k);
sonadd(xx,k%mod);
}
if(op==4){
scanf("%d",&xx);
sonsum(xx);
}
}
return 0;
}