rt 好像是线段树区间加有问题 也可能不是
#include<bits/stdc++.h>
#define ll long long
using namespace std;
inline ll read()
{
ll x=0,q=1;
char ch=getchar();
while(ch>'9'||ch<'0')
{
if(ch=='-')q=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9')
{
x=(x<<3)+(x<<1)+ch-'0';
ch=getchar();
}
return x*q;
}
const int maxn=1e5+6;
int n,m,r,mod,cnt;
int fa[maxn],dep[maxn],siz[maxn],son[maxn],id[maxn],top[maxn],rev[maxn];
ll t[maxn],w[maxn],a[maxn];
int laz[maxn];
vector<int >g[maxn];
inline void dfs1(int x,int f)
{
fa[x]=f;
dep[x]=dep[fa[x]]+1;
siz[x]=1;
for(register int i=0;i<g[x].size();i++)
{
int y=g[x][i];
if(y==f)continue;
dfs1(y,x);
siz[x]+=siz[y];
if(siz[y]>siz[son[x]])
son[x]=y;
}
}
inline void dfs2(int x,int topf)
{
id[x]=++cnt;
rev[cnt]=x;
w[cnt]=a[x];
top[x]=topf;
if(!son[x])return;
dfs2(son[x],topf);
for(register int i=0;i<g[x].size();i++)
{
int y=g[x][i];
if(y==fa[x]||y==son[x])continue;
dfs2(y,y);
}
}
inline void build(int x,int l,int r)
{
if(l==r)
{
t[x]=w[l]%mod;
return;
}
int mid=(l+r)>>1;
build(x<<1,l,mid);
build((x<<1)|1,mid+1,r);
t[x]=(t[x<<1]+t[(x<<1)|1])%mod;
}
inline void pushdown(int x,int l,int r)
{
int mid=(l+r)>>1;
t[x<<1]+=(mid-l+1)*laz[x];
t[(x<<1)|1]+=(r-mid)*laz[x];
t[x<<1]%=mod;
t[(x<<1)|1]%=mod;
laz[x<<1]+=laz[x];
laz[(x<<1)]+=laz[x];
laz[x]=0;
}
inline void add(int l,int r,int y,int lx,int rx,int x)
{
if(l<=lx&&r>=rx)
{
t[x]+=(rx-lx+1)*y;
laz[x]+=y;
t[x]%=mod;
laz[x]%=mod;
}
int mid=(lx+rx)>>1;
if(laz[x]&&lx!=rx)
pushdown(x,lx,rx);
if(l<=mid)
add(l,r,y,lx,mid,x<<1);
if(r>mid)
add(l,r,y,mid+1,rx,(x<<1)|1);
t[x]=(t[x<<1]+t[(x<<1)|1])%mod;
}
inline ll ask(int l,int r,int lx,int rx,int x)
{
if(l<=lx&&r>=rx)
return t[x];
int mid=(lx+rx)>>1;
if(laz[x]&&lx!=rx)
pushdown(x,lx,rx);
ll sum=0;
if(l<=mid)
sum+=ask(l,r,lx,mid,x<<1);
sum%=mod;
if(r>mid)
sum+=ask(l,r,mid+1,rx,(x<<1)|1);
sum%=mod;
return sum;
}
inline void addpath(int x,int y,int z)
{
while(top[x]!=top[y])
{
if(dep[top[x]]<dep[top[y]])swap(x,y);
add(id[top[x]],id[x],z,1,n,1);
x=fa[top[x]];
}
if(dep[x]>dep[y])swap(x,y);
add(id[x],id[y],z,1,n,1);
}
inline void addson(int x,int y)
{
add(id[x],id[x]+siz[x]-1,y,1,n,1);
}
inline ll askpath(int x,int y)
{
ll ans=0;
while(top[x]!=top[y])
{
if(dep[top[x]]<dep[top[y]])swap(x,y);
ans+=ask(id[top[x]],id[x],1,n,1);
ans%=mod;
x=fa[top[x]];
}
if(dep[x]>dep[y])swap(x,y);
ans+=ask(id[x],id[y],1,n,1);
ans%=mod;
return ans;
}
inline ll askson(int x)
{
ll ans=0;
ans=ask(id[x],id[x]+siz[x]-1,1,n,1);
return ans;
}
int main()
{
n=read(),m=read(),r=read(),mod=read();
for(register int i=1;i<=n;i++)
a[i]=read();
for(register int i=1;i<n;i++)
{
int x,y;
x=read(),y=read();
g[x].push_back(y);
g[y].push_back(x);
}
dfs1(r,0);
dfs2(r,r);
build(1,1,n);
while(m--)
{
int opt,x,y,z;
opt=read();
if(opt==1)
{
x=read(),y=read(),z=read(),z%=mod;
addpath(x,y,z);
}
if(opt==2)
{
x=read(),y=read();
cout<<askpath(x,y)<<endl;
}
if(opt==3)
{
x=read(),y=read(),y%=mod;
addson(x,y);
}
if(opt==4)
{
x=read();
cout<<askson(x)<<endl;
}
}
return 0;
}