用的vector,是只能用链式前向星吗
#include<bits/stdc++.h>
#define ll long long
#define debug printf("ciallo\n")
#define rep(i,aaa,bbb) for(int i=(aaa);i<=(bbb);i++)
#define per(i,aaa,bbb) for(int i=(aaa);i>=(bbb);i--)
#define pb push_back
#define mid ((l+r)>>1)
#define lson x<<1,l,mid
#define rson x<<1|1,mid+1,r
#define len (r-l+1)
using namespace std;
int read(){
int f=1,x=0;
char c=getchar();
while(c>'9'||c<'0'){
if(c=='-') f=-1;
c=getchar();
}
while(c>='0'&&c<='9'){
x=(x<<1)+(x<<3)+(c^48);
c=getchar();
}
return x*f;
}
const int inf=0x7fffffff;
const int maxn=1e5+10;
int n,m,root,mod;
int w[maxn],cnt;
vector<int>t[maxn];
int dep[maxn],fa[maxn],size[maxn],son[maxn],top[maxn];//true index
int id[maxn],wt[maxn];//index in T,using Tfunction need id[x]
//xds------------------------------------
struct node{
int x,add;
}T[maxn<<2];
void build(int x,int l,int r){
if(l==r){
T[x].x=wt[l];
return;
}
build(lson);
build(rson);
}
inline void down(int x,int l,int r){
if(T[x].add==0)return;
T[x<<1].add+=T[x].add;
T[x<<1|1].add+=T[x].add;
T[x].x+=T[x].add*len;
T[x].x%=mod;
T[x<<1].add%=mod;
T[x<<1|1].add%=mod;
T[x].add=0;
}
void rewrite(int x,int l,int r,int lq,int rq,int vl){
if(l>=lq&&r<=rq){
T[x].add=(T[x].add+vl)%mod;
}
down(x,l,r);
if(lq<=mid)rewrite(lson,lq,rq,vl);
if(rq>mid)rewrite(rson,lq,rq,vl);
}
int count(int x,int l,int r,int lq,int rq){
if(l!=r)down(x,l,r);
if(l>=lq&&r<=rq)return T[x].x;
ll ccc=0;
if(lq<=mid)ccc+=count(lson,lq,rq);
ccc%=mod;
if(rq>mid)ccc+=count(rson,lq,rq);
return ccc%mod;
}
//---------------------------------------
void dfs1(int x,int f,int deep){
dep[x]=deep;
fa[x]=f;
int mmm=-1;
for(int i:t[x]){
if(i!=f){
dfs1(i,x,deep+1);
size[x]+=size[i];
if(size[i]>mmm)mmm=size[i],son[x]=i;
}
}
}
void dfs2(int x,int f){
id[x]=++cnt;
wt[cnt]=wt[x];
top[x]=f;
if(!son[x])return;
dfs2(son[x],f);
for(int i:t[x]){
if(i!=fa[x]&&i!=son[x]){
dfs2(i,i);
}
}
}
inline void q1(int x,int y,int z){
z%=mod;
while(top[x]!=top[y]){
if(dep[top[x]]<dep[top[y]])swap(x,y);
rewrite(1,1,n,id[top[x]],id[x],z);
x=fa[top[x]];
}
if(dep[x]<dep[y])swap(x,y);
rewrite(1,1,n,id[y],id[x],z);
}
inline int q2(int x,int y){
ll ans=0;
while(top[x]!=top[y]){
if(dep[top[x]]<dep[top[y]])swap(x,y);
ans=(ans+count(1,1,n,id[top[x]],id[x]))%mod;
x=fa[top[x]];
}
if(dep[x]<dep[y])swap(x,y);
return (ans+count(1,1,n,id[y],id[x]))%mod;
}
inline void q3(int x,int z){
rewrite(1,1,n,id[x],id[x]+size[x]-1,z);
}
inline int q4(int x){
return count(1,1,n,id[x],id[x]+size[x]-1);
}
int main(){
n=read(),m=read(),root=read(),mod=read();
rep(i,1,n)w[i]=read()%mod;
rep(i,2,n){
int u=read(),v=read();
t[u].pb(v),t[v].pb(u);
}
dfs1(root,0,0);
dfs2(root,0);
build(1,1,n);
while(m--){
int k=read();
if(k==1){
int x=read(),y=read(),z=read();
q1(x,y,z);
}
if(k==2){
int x=read(),y=read();
printf("%d\n",q2(x,y));
}
if(k==3){
int x=read(),z=read();
q3(x,z);
}
if(k==4){
int x=read();
printf("%d\n",q4(x));
}
}
return 0;
}