#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=114514;
int cdfn,cnt=1,n,q,r,p;
int fa[N],dep[N],Size[N],son[N],t[N],top[N],dfn[N],a[N];
int tree[N*4],tag[N*4],head[N],to[N*2],nxt[N*2];
void pushup(int cur){
tree[cur]=(tree[cur*2]+tree[cur*2+1])%p;
return;
}
void addtag(int cur,int lt,int rt,int val){
tag[cur]=(tag[cur]+val)%p;
tree[cur]=(tree[cur]+(rt-lt+1)*val)%p;
return;
}
void build(int cur,int lt,int rt){
if(lt==rt){
tree[cur]=a[t[lt]];
return;
}
int mid=(lt+rt)>>1;
build(cur*2,lt,mid);
build(cur*2+1,mid+1,rt);
pushup(cur);
return;
}
void pushdown(int cur,int lt,int rt){
if(tag[cur]==0)return;
int mid=(lt+rt)>>1;
addtag(2*cur,lt,mid,tag[cur]);
addtag(2*cur+1,mid+1,rt,tag[cur]);
tag[cur]=0;
return;
}
int query(int cur,int lt,int rt,int qx,int qy){
if(qx>rt||qy<lt)return 0;
if(qx<=lt&&qy>=rt)return tree[cur];
pushdown(cur,lt,rt);
int mid=(lt+rt)>>1;
return (query(cur*2,lt,mid,qx,qy)+query(cur*2+1,mid+1,rt,qx,qy))%p;
}
void update(int cur,int lt,int rt,int qx,int qy,int val){
if(qx>rt||qy<lt)return;
if(qx<=lt&&qy>=rt){
addtag(cur,lt,rt,val);
return;
}
pushdown(cur,lt,rt);
int mid=(lt+rt)>>1;
update(cur*2,lt,mid,qx,qy,val);
update(cur*2+1,mid+1,rt,qx,qy,val);
pushup(cur);
return;
}
void single(int a,int b){
cnt++;
to[cnt]=b;
nxt[cnt]=head[a];
head[a]=cnt;
return;
}
void add(int a,int b){
single(a,b);
single(b,a);
}
void dfs1(int cur,int Fa,int Dep){
fa[cur]=Fa;
dep[cur]=Dep;
Size[cur]=1;
for(int i=head[cur];i;i=nxt[i]){
if(to[i]==Fa)continue;
dfs1(to[i],cur,Dep+1);
Size[cur]+=Size[to[i]];
if(Size[to[i]]>Size[son[cur]])son[cur]=to[i];
}
}
void dfs2(int cur,int tp){
cdfn++;
dfn[cur]=cdfn;
t[cdfn]=cur;
top[cur]=tp;
if(!son[cur])return;
dfs2(son[cur],tp);
for(int i=head[cur];i;i=nxt[i]){
if(to[i]==fa[cur]||to[i]==son[cur])continue;
dfs2(to[i],to[i]);
}
}
void addt(int cur,int v){
update(1,1,n,dfn[cur],dfn[cur]+Size[cur]-1,v);
}
int qut(int cur){
return query(1,1,n,dfn[cur],dfn[cur]+Size[cur]-1);
}
void addl(int From,int To,int val){
val%=p;
while(top[From]!=top[To]){
if(dep[From]<dep[To])swap(From,To);
update(1,1,n,dfn[top[From]],dfn[From],val);
From=fa[top[From]];
}
if(dep[From]>dep[To])swap(From,To);
update(1,1,n,dfn[From],dfn[To],val);
return;
}
int quel(int From,int To){
int ans=0;
while(top[From]!=top[To]){
if(dep[From]<dep[To])swap(From,To);
ans=(ans+query(1,1,n,dfn[top[From]],dfn[From]))%p;
From=fa[top[From]];
}
if(dep[From]>dep[To])swap(From,To);
ans=(ans+query(1,1,n,dfn[From],dfn[To]))%p;
return ans%p;
}
signed main(){
cin>>n>>q>>r>>p;
for(int i=1;i<=n;i++)cin>>a[i];
int jsad,jfbh;
for(int i=1;i<n;i++){
cin>>jsad>>jfbh;
add(jsad,jfbh);
}
dfs1(r,0,1);
dfs2(r,r);
build(1,1,n);
for(int i=1;i<=n;i++){
cout<<i<<":"<<Size[]
}
for(int i=1;i<=q;i++){
int opt,a,b,c;
cin>>opt>>a;
if(opt==3){cin>>b;addt(a,b);}
if(opt==1){cin>>b>>c;addl(a,b,c);}
if(opt==2){cin>>b;cout<<quel(a,b)<<endl;}
if(opt==4){cout<<qut(a)<<endl;}
}
return 0;
}
一,三点可过,其他全wa