过不了样例……实在看不出来哪里寄了
#include<bits/stdc++.h>
using namespace std;
int n,m,r;
struct nd{
int l,r,mid;
long long s,ad;
}t[2000005];
int hd[500005],cnt=0,op;
int son[500005],tp[500005],cct,fa[500005],sz[500005],de[500005],ctn[500005];
long long yw[500005],nw[500005],x,y,z,q;
struct E{
int v,nt;
}e[500005];
void dfs1(int p,int f,int ndp){
de[p]=ndp;
int yy,mxs=-1;
sz[p]=1;
for(int i = hd[p];i;i = e[i].nt){
yy = e[i].v;
if(yy == f)continue;
fa[yy]=p;
dfs1(yy,p,ndp+1);
sz[p]+=sz[yy];
if(sz[yy]>mxs){
mxs=sz[yy];son[p]=yy;
}
}
}
void dfs2(int p,int f,int topn){
int yy;
ctn[p]=++cct;
nw[cct]=yw[p];
tp[p]=topn;
if(!son[p])return;
dfs2(son[p],p,topn);
for(int i = hd[p];i;i = e[i].nt){
yy = e[i].v;
if(yy==son[p]||yy==f)continue;
dfs2(yy,p,yy);
}
}
void add(int u,int v){
e[cnt].v = v;
e[cnt].nt = hd[u];
hd[u] = cnt++;
}
void ud(int p){
t[p].s = t[p*2].s + t[p*2+1].s;
t[p].s%=q;
}
void tag(int p){
if(t[p].ad){
t[p*2].s+=t[p].ad;
t[p*2].s%=q;
t[p*2+1].s+=t[p].ad;
t[p*2+1].s%=q;
t[p*2].ad+=t[p].ad;
t[p*2].ad%=q;
t[p*2+1].ad+=t[p].ad;
t[p*2+1].ad%=q;
t[p].ad=0;
}
}
void build(int p,int l,int r){
t[p].l = l;t[p].r = r;
t[p].mid = l+r>>1;
if(l==r){
t[p].s = nw[l]%q;
return;
}
build(p*2,l,t[p].mid);
build(p*2+1,t[p].mid+1,r);
ud(p);
}
long long qr(int p,int l,int r){
if(t[p].l>=l&&t[p].r<=r){
return t[p].s;
}
tag(p);
long long val=0;
if(t[p].mid>=l)val+=qr(p*2,l,r);
if(t[p].mid<r)val+=qr(p*2+1,l,r);
return val%q;
}
void aq(int p,int l,int r,long long k){
if(t[p].l>=l&&t[p].r<=r){
t[p].s+=k;
t[p].ad+=k;
t[p].s%=q;
t[p].ad%=k;
return;
}
tag(p);
if(t[p].mid>=l)aq(p*2,l,r,k);
if(t[p].mid<r)aq(p*2+1,l,r,k);
ud(p);
}
void aqot(int nx,int ny,long long k){
while(tp[nx]!=tp[ny]){
if(de[tp[nx]]<de[tp[ny]])swap(nx,ny);
aq(1,ctn[tp[nx]],ctn[nx],k);
nx = fa[tp[nx]];
}
if(de[nx]<de[ny])swap(nx,ny);
aq(1,ctn[ny],ctn[nx],k);
}
long long qrot(int nx,int ny){
long long sum=0;
while(tp[nx]!=tp[ny]){
if(de[tp[nx]]<de[tp[ny]])swap(nx,ny);
sum+=qr(1,ctn[tp[nx]],ctn[nx]);
sum%=q;
nx = fa[tp[nx]];
}
if(de[nx]<de[ny])swap(nx,ny);
sum+=qr(1,ctn[ny],ctn[nx]);
return sum%q;
}
void aqoot(int p,long long k){
aq(1,ctn[p],ctn[p]+sz[p]-1,k);
}
long long qroot(int p){
return qr(1,ctn[p],ctn[p]+sz[p]-1);
}
int main(){
scanf("%d%d%d%lld",&n,&m,&r,&q);
for(int i = 1;i<=n;i++){
scanf("%lld",&yw[i]);
}
for(int i = 1;i<n;i++){
scanf("%lld%lld",&x,&y);
add(x,y);add(y,x);
}
dfs1(r,0,1);
dfs2(r,0,r);
build(1,1,n);
while(m--){
scanf("%d",&op);
if(op==1){
scanf("%lld%lld%lld",&x,&y,&z);
aqot(x,y,z);
}else if(op==2){
scanf("%lld%lld",&x,&y);
printf("%lld\n",qrot(x,y));
}else if(op==3){
scanf("%lld%lld",&x,&y);
aqoot(x,y);
}else{
scanf("%lld",&x);
printf("%lld\n",qroot(x));
}
}
return 0;
}