样例输出第二个值是9
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#define N 100010
#define ll long long
using namespace std;
ll n,t,r,p,X,Y,Z;
ll Root[N],Next[N<<1],v[N<<1],cnt=0;
ll d[N],a[N],id[N],cur[N],fa[N],son[N],size[N],top[N],tot=0;
struct node{
ll l,r,sum,tag;
}c[N<<2];
inline void add(ll _u,ll _v)
{
v[++cnt]=_v;
Next[cnt]=Root[_u];
Root[_u]=cnt;
}
void dfs1(ll u)
{
size[u]=1;
for(ll x=Root[u];x!=0;x=Next[x])
if(v[x]!=fa[u]){
d[v[x]]=d[u]+1,fa[v[x]]=u;//初始化d和fa
dfs1(v[x]),size[u]+=size[v[x]];//遍历子树, 更新size
if(size[v[x]]>size[son[u]])son[u]=v[x];//更新重儿子
}
}
void dfs2(ll u,ll t)
{
id[u]=++tot/*时间戳*/,cur[tot]=a[u],top[u]=t;//将u加入dfs序
if(son[u])dfs2(son[u],t);//先处理重儿子
for(ll x=Root[u];x!=0;x=Next[x])//处理其他轻儿子, 轻儿子自己做重链头
if(v[x]!=fa[u]&&v[x]!=son[u])
dfs2(v[x],v[x]);
}
void update(ll x)
{
c[x].sum=(c[x<<1].sum+c[x<<1|1].sum)%p;
}
void pushdown(ll x){
if(c[x].tag){
c[x<<1].sum=(c[x<<1].sum+c[x].tag*(c[x<<1].r-c[x<<1].l+1))%p;
c[x<<1|1].sum=(c[x<<1|1].sum+c[x].tag*(c[x<<1|1].r-c[x<<1|1].l+1))%p;
c[x<<1].tag=(c[x<<1].tag+c[x].tag)%p;
c[x<<1|1].tag=(c[x<<1|1].tag+c[x].tag)%p;
c[x].tag=0;
}
}
void build(ll l,ll r,ll x)
{
c[x].l=l,c[x].r=r;
if(l==r){
c[x].sum=cur[x];
return;
}
ll mid=(l+r)>>1;
build(l,mid,x<<1);
build(mid+1,r,x<<1|1);
update(x);
}
ll query(ll l,ll r,ll x)
{
if(c[x].l>=l&&c[x].r<=r)
return c[x].sum;
pushdown(x);
ll mid=(c[x].l+c[x].r)>>1;
ll ans=0;
if(l<=mid)ans=(ans+query(l,r,x<<1))%p;
if(r>mid)ans=(ans+query(l,r,x<<1|1))%p;
return ans%p;
}
void change(ll l,ll r,ll z,ll x)
{
if(c[x].l>=l&&c[x].r<=r){
c[x].sum+=z*(c[x].r-c[x].l+1);
c[x].tag+=z;
return;
}
pushdown(x);
ll mid=(c[x].l+c[x].r)>>1;
if(l<=mid)change(l,r,x<<1,z);
if(r>mid)change(l,r,x<<1|1,z);
update(x);
}
inline ll calsum(ll x,ll y)
{
ll res=0;
while(top[x]!=top[y]){
if(d[top[x]]<d[top[y]])
swap(x,y);
res=(res+query(id[top[x]],id[x],1))%p;
x=fa[top[x]];
}
if(d[x]>d[y])swap(x,y);
res=(res+query(id[x],id[y],1))%p;
return res;
}
inline void treeadd(ll x,ll y,ll z)
{
while(top[x]!=top[y]){
if(d[top[x]]<d[top[y]])
swap(x,y);
change(id[top[x]],id[x],z,1);
x=fa[top[x]];
}
if(d[x]>d[y])swap(x,y);
change(id[x],id[y],z,1);
}
int main()
{
scanf("%lld%lld%lld%lld",&n,&t,&r,&p);
for(ll i=1;i<=n;++i)scanf("%lld",&a[i]);
for(ll i=1;i<=n-1;++i){
scanf("%lld%lld",&X,&Y);
add(X,Y),add(Y,X);
}
dfs1(r);
dfs2(r,r);
build(1,n,1);
while(t--){
int opt;
scanf("%d",&opt);
if(opt==1){
scanf("%lld%lld%lld",&X,&Y,&Z);
treeadd(X,Y,Z%p);
}
if(opt==2){
scanf("%lld%lld",&X,&Y);
printf("%lld\n",calsum(X,Y)%p);
}
if(opt==3){
scanf("%lld%lld",&X,&Z);
change(id[X],id[X]+size[X]-1,Z%p,1);
}
if(opt==4){
scanf("%lld",&X);
printf("%lld\n",query(id[X],id[X]+size[X]-1,1)%p);
}
}
return 0;
}