大神请勿看,代码又臭又长。。。
#include<bits/stdc++.h>
#define N 100010
using namespace std;
int n,m,r;
int v[N],id[N],son[N],top[N],f[N],pos[N],d[N],siz[N];
int out[N],cnt=0;
long long p;
struct Node{
int l,r,sum,flag;
}t[3*N];
void build(int k,int l,int r){
t[k].flag=0;
t[k].l=l,t[k].r=r;
if(l==r){
t[k].sum=v[id[l]];
return;
}
int mid=(l+r)>>1;
build(k<<1,l,mid);
build(k<<1|1,mid+1,r);
t[k].sum=(t[k<<1].sum+t[k<<1|1].sum)%p;
}
void tag(int k){
long long x=t[k].flag;
t[k<<1].flag=(t[k<<1].flag+x)%p;
t[k<<1].sum=(t[k<<1].sum+(t[k<<1].r-t[k<<1].l+1)*x)%p;
t[k<<1|1].flag=(t[k<<1|1].flag+x)%p;
t[k<<1|1].sum=(t[k<<1|1].sum+(t[k<<1|1].r-t[k<<1|1].l+1)*x)%p;
}
void modify(int k,int l,int r,long long v){
int L=t[k].l,R=t[k].r;
if(l<=L&&R<=r){
t[k].flag=(t[k].flag+v)%p;
t[k].sum=(t[k].sum+(R-L+1)*v)%p;
return;
}
if(t[k].flag) tag(k);
int mid=(L+R)>>1;
if(l<=mid&&mid<r){
modify(k<<1,l,mid,v);
modify(k<<1|1,mid+1,r,v);
}
if(r<=mid) modify(k<<1,l,r,v);
if(l>mid) modify(k<<1|1,l,r,v);
t[k].sum=(t[k<<1].sum+t[k<<1|1].sum)%p;
}
long long query(int k,int l,int r){
int L=t[k].l,R=t[k].r;
if(l<=L&&R<=r) return t[k].sum;
if(t[k].flag) tag(k);
int mid=(L+R)>>1;
if(r<=mid) return query(k<<1,l,r);
if(l>mid) return query(k<<1|1,l,r);
return (query(k<<1,l,mid)+query(k<<1|1,mid+1,r))%p;
}
vector<int> e[N];
void dfs_1(int x,int fa,int dep){
d[x]=dep;
siz[x]=1;
f[x]=fa;
for(int i=0;i<e[x].size();i++){
int k=e[x][i];
if(k==fa) continue;
dfs_1(k,x,dep+1);
siz[x]+=siz[k];
if(siz[son[x]]<siz[k]) son[x]=k;
}
}
void dfs_2(int x,int tp){
top[x]=tp;
pos[x]=out[x]=++cnt;
id[cnt]=x;
if(son[x]) dfs_2(son[x],tp);
for(int i=0;i<e[x].size();i++){
int k=e[x][i];
if(k==son[x]||k==f[x]) continue;
dfs_2(k,k);
out[x]=max(out[x],out[k]);
}
for(int i=0;i<e[x].size();i++){
int k=e[x][i];
out[x]=max(out[x],out[k]);
}
}
int lca(int x,int y){
for(;top[x]!=top[y];){
if(d[top[x]]<d[top[y]]) swap(x,y);
x=f[top[x]];
}
return d[x]>d[y]?y:x;
}
void solve(int x,int y,long long v){
int tx=top[x],ty=top[y];
while(tx!=ty){
if(d[tx]<d[ty]){
swap(tx,ty);
swap(x,y);
}
modify(1,pos[tx],pos[x],v);
x=f[tx];
tx=top[x];
}
if(d[x]>d[y]) swap(x,y);
modify(1,pos[x],pos[y],v);
}
long long query(int x,int y){
long long sum=0;
int tx=top[x],ty=top[y];
while(tx!=ty){
if(d[tx]<d[ty]){
swap(tx,ty);
swap(x,y);
}
sum=(sum+query(1,pos[tx],pos[x]))%p;
x=f[tx];
tx=top[x];
}
if(d[x]>d[y]) swap(x,y);
sum=(sum+query(1,pos[x],pos[y]))%p;
return sum;
}
int main(){
scanf("%d%d%d%lld",&n,&m,&r,&p);
for(int i=1;i<=n;i++) scanf("%lld",&v[i]);
for(int i=1;i<n;i++){
int x,y;
scanf("%d%d",&x,&y);
e[x].push_back(y);
e[y].push_back(x);
}
dfs_1(r,0,0);
dfs_2(r,r);
build(1,1,n);
for(int i=1;i<=m;i++){
int key;
scanf("%d",&key);
if(key==1){
int x,y;
long long v;
scanf("%d%d%lld",&x,&y,&v);
solve(x,y,v);
}
if(key==2){
int x,y;
scanf("%d%d",&x,&y);
printf("%lld\n",query(x,y));
}
if(key==3){
int x;
long long v;
scanf("%d%lld",&x,&v);
modify(1,pos[x],out[x],v);
}
if(key==4){
int x;
scanf("%d",&x);
printf("%lld\n",query(1,pos[x],out[x]));
}
}
return 0;
}