提交10分,其他全WA了,检查了很久都没查出来
#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<queue>
#define INF 0x3f3f3f3f
#define int long long
using namespace std;
typedef long long ll;
const int N=1e5+10;
int n,m,r,p,a[N];
int head[N],ne;
struct Edge {
int v,nxt;
}e[N<<1];
struct Tree {
int l,r,sum,add;
}t[N<<2];
void init() {
memset(head,-1,sizeof(head));
ne=0;
}
void add_edge(int u,int v) {
e[ne].v=v;
e[ne].nxt=head[u];
head[u]=ne++;
}
int dep[N],son[N],size[N],top[N],fa[N],rnk[N],dfn[N],cnt;
void dfs1(int x,int pre) {
fa[x]=pre;
size[x]=1;
dep[x]=dep[pre]+1;
for(int i=head[x];i!=-1;i=e[i].nxt) {
int v=e[i].v;
if(v==pre) continue;
dfs1(v,x);
size[x]+=size[v];
if(size[v]>size[son[x]]) son[x]=v;
}
}
void dfs2(int x,int pre) {
dfn[++cnt]=x;
rnk[x]=cnt;
top[x]=pre;
if(!son[x]) return;
dfs2(son[x],pre);
for(int i=head[x];i!=-1;i=e[i].nxt) {
int v=e[i].v;
if(v==fa[x]||v==son[x]) continue;
dfs2(v,v);
}
}
void pushup(int rt) {
t[rt].sum=t[rt<<1].sum+t[rt<<1|1].sum;
}
void build(int rt,int l,int r) {
t[rt].l=l;
t[rt].r=r;
if(l==r) {
t[rt].sum=a[dfn[l]];
return;
}
int mid=(l+r)>>1;
build(rt<<1,l,mid);
build(rt<<1|1,mid+1,r);
pushup(rt);
}
void pushdown(int rt) {
if(t[rt].add==0) return;
t[rt<<1].sum+=(t[rt<<1].r-t[rt<<1].l+1)*t[rt].add;
t[rt<<1].sum%=p;
t[rt<<1|1].sum+=(t[rt<<1|1].r-t[rt<<1|1].l+1)*t[rt].add;
t[rt<<1|1].sum%=p;
t[rt<<1].add+=t[rt].add;
t[rt<<1].sum%=p;
t[rt<<1|1].add+=t[rt].add;
t[rt<<1|1].sum%=p;
t[rt].add=0;
}
void update(int rt,int L,int R,int v) {
if(L<=t[rt].l&&t[rt].r<=R) {
t[rt].sum+=v*(t[rt].r-t[rt].l+1);
t[rt].sum%=p;
t[rt].add+=v;
t[rt].add%=p;
return;
}
pushdown(rt);
int mid=(t[rt].l+t[rt].r)>>1;
if(L<=mid) {
update(rt<<1,L,R,v);
}
if(R>mid) {
update(rt<<1|1,L,R,v);
}
}
int query(int rt,int L,int R) {
if(L<=t[rt].l&&t[rt].r<=R) {
return t[rt].sum;
}
pushdown(rt);
int mid=(t[rt].l+t[rt].r)>>1,ret=0;
if(L<=mid) {
ret+=query(rt<<1,L,R);
ret%=p;
}
if(R>mid) {
ret+=query(rt<<1|1,L,R);
ret%=p;
}
return ret;
}
void tree_update(int x,int y,int z) {
while(top[x]!=top[y]) {
if(dep[top[x]]<dep[top[y]]) swap(x,y);
update(1,rnk[top[x]],rnk[x],z);
x=fa[top[x]];
}
if(dep[x]<dep[y]) swap(x,y);
update(1,rnk[y],rnk[x],z);
}
int tree_query(int x,int y) {
int ret=0;
while(top[x]!=top[y]) {
if(dep[top[x]]<dep[top[y]]) swap(x,y);
ret+=query(1,rnk[top[x]],rnk[x]);
ret%=p;
x=fa[top[x]];
}
if(dep[x]<dep[y]) swap(x,y);
ret+=query(1,rnk[y],rnk[x]);
ret%=p;
return ret;
}
signed main() {
init();
scanf("%lld%lld%lld%lld",&n,&m,&r,&p);
for(int i=1;i<=n;i++) scanf("%lld",&a[i]);
for(int i=1;i<n;i++) {
int u,v;
scanf("%lld%lld",&u,&v);
add_edge(u,v);
add_edge(v,u);
}
dfs1(r,r);
dfs2(r,r);
build(1,1,n);
while(m--) {
int op,x,y,z;
scanf("%lld",&op);
if(op==1) {
scanf("%lld%lld%lld",&x,&y,&z);
tree_update(x,y,z);
}
else if(op==2) {
scanf("%lld%lld",&x,&y);
printf("%lld\n",tree_query(x,y));
}
else if(op==3) {
scanf("%lld%lld",&x,&z);
update(1,rnk[x],rnk[x]+size[x]-1,z);
}
else {
scanf("%lld",&x);
printf("%lld\n",query(1,rnk[x],rnk[x]+size[x]-1));
}
}
return 0;
}