我知道这不太厚道但是半个上午了没弄出来哪里寄了所以有没有神仙帮忙看看 就是树剖板子
然后操作 3 死循环了
#include<iostream>
#define lc p<<1
#define rc p<<1|1
#define int long long
using namespace std;
const int N=1e5+10;
int n,m,rt,mod;
int a[N],w[N];
struct SegmentTree{
int l,r,sum,add;
#define l(p) t[p].l
#define r(p) t[p].r
#define add(p) t[p].add
#define sum(p) t[p].sum
}t[N<<2];
void build(int l,int r,int p){
l(p)=l,r(p)=r;
if(l==r){
sum(p)=w[l];//***
return ;
}
int mid=l+r>>1;
build(lc,l,mid);
build(rc,mid+1,r);
sum(p)=sum(lc)+sum(rc);
}
void pushdown(int p){
if(add(p)){
add(lc)+=add(p);
add(rc)+=add(p);
sum(lc)+=add(p)*(r(lc)-l(lc)+1);
sum(rc)+=add(p)*(r(rc)-l(rc)+1);
add(p)=0;
}
}
void Tree_add(int p,int l,int r,int v){
if(l<=l(p) && r(p)<=r){
sum(p)+=v*(r(p)-l(p)+1);
add(p)+=v; return ;
}
pushdown(p);
int mid=l(p)+r(p)>>1;
if(l<=mid) Tree_add(lc,l,r,v);
if(r>mid) Tree_add(rc,l,r,v);
sum(p)=sum(lc)+sum(rc);
}
int Tree_query(int p,int l,int r){
if(l<=l(p) && r(p)<=r){
return sum(p);
}
pushdown(p);
int mid=l(p)+r(p)>>1,res=0;
if(l<=mid) res+=Tree_query(lc,l,r);
if(r>mid) res+=Tree_query(rc,l,r);
return res;
}
int ver[N<<1],ne[N<<1],he[N],tot;
void add_edge(int u,int v){
ver[++tot]=v;
ne[tot]=he[u];
he[u]=++tot;
}
int fa[N],dep[N],top[N],siz[N],son[N],id[N];
void dfs1(int u,int from,int d){
dep[u]=d; fa[u]=from; siz[u]=1;
int maxx=-999999999;
for(int i=he[u];i;i=ne[i]){
int v=ver[i];
if(v==from) continue;
dfs1(v,u,d+1);
siz[u]+=siz[v];
if(siz[v]>maxx) son[u]=v,maxx=siz[v];
}
}
void dfs2(int u,int from){
id[u]=++tot;/*dfs 序*/ w[tot]=a[u]; top[u]=from;
if(!son[u]) return;
dfs2(son[u],from);
for(int i=he[u];i;i=ne[i]){
int v=ver[i];
if(v==from || v==son[u]) continue;
dfs2(v,v);
}
}
int update(int x,int y,int v){
while(top[x]!=top[y]){
if(dep[top[x]]<dep[top[y]]) swap(x,y);
Tree_add(1,id[top[x]],id[x],v);
x=fa[top[x]];
}
if(dep[x]<dep[y]) swap(x,y);
Tree_add(1,id[y],id[x],v);
}
int query(int x,int y){
int res=0;
while(top[x]!=top[y]){
if(dep[top[x]]<dep[top[y]]) swap(x,y);
res+=Tree_query(1,id[top[x]],id[x]); res%=mod;
x=fa[top[x]];
}
if(dep[x]<dep[y]) swap(x,y);
res+=Tree_query(1,id[y],id[x]);
return res;
}
void update1(int x,int v){
Tree_add(1,id[x],id[x]+siz[x]-1,v);
}
int query1(int x){
return Tree_query(1,id[x],id[x]+siz[x]-1);
}
signed main(){
cin>>n>>m>>rt>>mod;
for(int i=1;i<=n;++i) scanf("%lld",&w[i]);
for(int i=1;i<n;++i){
int x,y; scanf("%lld%lld",&x,&y);
add_edge(x,y); add_edge(y,x);
}
tot=0;
dfs1(rt,0,1);
dfs2(rt,rt);
build(1,1,n);
while(m--){
int op,x,y,z;
scanf("%lld",&op);
if(op==1){
scanf("%lld%lld%lld",&x,&y,&z);
update(x,y,z);
}
else if(op==2){
scanf("%lld%lld",&x,&y);
printf("%lld\n",query(x,y));
}
else if(op==3){
scanf("%lld%lld",&x,&z);
update1(x,z);
}
else{
scanf("%lld",&x);
printf("%lld\n",query1(x));
}
}
return 0;
}