#include<bits/stdc++.h>
#define int long long
const int N=1e5+10;
using namespace std;
int n,m,root,p;
int a[N],b[N];
vector<int> edge[N];
int size[N],fa[N],son[N],dep[N];
int l[N],r[N],top[N],cnt;
struct node{
int tag,sum;
}data[N*4];
void update(int x){
data[x].sum=(data[x*2].sum+data[x*2+1].sum)%p;
}
void build(int x,int l,int r){
if(l==r){
data[x].sum=b[l]%p;
data[x].tag=0;
return ;
}
int mid=l+r>>1;
build(x*2,l,mid);
build(x*2+1,mid+1,r);
update(x);
}
void dfs1(int x){
size[x]=1;
for(int i=0;i<edge[x].size();i++){
int y=edge[x][i];
if(y!=fa[x]){
fa[y]=x;
dep[y]=dep[x]+1;
dfs1(y);
size[x]+=size[y];
if(size[y]>size[son[x]]) son[x]=y;
}
}
}
void dfs2(int x,int t){
l[x]=++cnt;
b[cnt]=a[x];
top[x]=t;
if(son[x]) dfs2(son[x],t);
for(int i=0;i<edge[x].size();i++){
int y=edge[x][i];
if(y!=fa[x]&&y!=son[x]) dfs2(y,y);
}
r[x]=cnt;
}
void maketag(int x,int k,int L,int R){
data[x].tag+=k;
data[x].tag%=k;
data[x].sum+=k*(R-L+1)%p;
data[x].sum%=p;
}
void pushdown(int x,int L,int R){
if(L!=R){
int mid=L+R>>1;
maketag(x*2,data[x].tag,L,mid);
maketag(x*2+1,data[x].tag,L,mid);
data[x].tag=0;
}
}
void modify2(int x,int l,int r,int k,int L,int R){
pushdown(x,L,R);
if(l<=L&&r<=R){
maketag(x,k,L,R);
return ;
}
int mid=L+R>>1;
if(r<=mid) modify2(x*2,l,r,k,L,mid);
else if(l>=mid+1) modify2(x*2+1,l,r,k,mid+1,R);
else{
modify2(x*2,l,r,k,L,mid);
modify2(x*2+1,l,r,k,mid+1,R);
}
update(x);
}
void modify1(int x,int y,int z){
while(top[x]!=top[y]){
if(dep[top[x]]<dep[top[y]]) swap(x,y);
modify2(1,l[top[x]],l[x],z,1,n);
x=fa[top[x]];
}
if(dep[x]<dep[y]) swap(x,y);
modify2(1,l[y],l[x],z,1,n);
}
int find2(int x,int l,int r,int L,int R){
pushdown(x,L,R);
if(l<=L&&r>=R) return data[x].sum;
int mid=L+R>>1;
if(r<=mid) return find2(x*2,l,r,L,mid);
else if(l>=mid+1) return find2(x*2+1,l,r,mid+1,R);
return (find2(x*2,l,r,L,mid)+find2(x*2+1,l,r,mid+1,R))%p;
}
int find1(int x,int y){
int ans=0;
while(top[x]!=top[y]){
if(dep[top[x]]<dep[top[y]]) swap(x,y);
ans+=find2(1,l[top[x]],l[x],1,n);
ans%=p;
x=fa[top[x]];
}
if(dep[x]<dep[y]) swap(x,y);
ans+=find2(1,l[y],l[x],1,n);
ans%=p;
return ans;
}
signed main(){
//freopen(".in","r",stdin);
//freopen(".out","w",stdout);
cin.tie(0)->sync_with_stdio(0);
cin>>n>>m>>root>>p;
for(int i=1;i<=n;i++) cin>>a[i];
for(int i=1;i<n;i++){
int x,y;
cin>>x>>y;
edge[x].push_back(y);
edge[y].push_back(x);
}
dfs1(root);
dfs2(root,root);
build(1,1,n);
while(m--){
int opt,x,y,z;
cin>>opt;
if(opt==1){
cin>>x>>y>>z;
modify1(x,y,z);
}
else if(opt==2){
cin>>x>>y;
cout<<find1(x,y)<<'\n';
}
else if(opt==3){
cin>>x>>z;
modify2(1,l[x],r[x],z,1,n);
}
else{
cin>>x;
cout<<find2(1,l[x],r[x],1,n)<<'\n';
}
}
return 0;
}
没有输出,可能是死循环了吧……