#include<bits/stdc++.h>
typedef long long ll;
namespace IO{
static const int bsize=1000000;
static unsigned char buf[bsize];
static int len,pos;
bool isEOF(){
if(pos==len){
pos=0;
len=fread(buf,1,bsize,stdin);
if(pos==len)return 1;
}
return 0;
}
char gc(){
return isEOF()?EOF:buf[pos++];
}
int rint(){
int x=0;
char c=gc();
for(;c<48||c>57;c=gc());
for(;c>=48&&c<=57;c=gc())
x=(x<<1)+(x<<3)+(c^48);
return x;
}
template<typename T>
void read(T&x){x=rint();}
template<typename T,typename...Ts>
inline void read(T&x,Ts&...rest){
read(x);
read(rest...);
}
}
using IO::read;
using namespace std;
const int N=1e5+1,M=2e5+1;
int n,m,r,p,o,u,v,w,dfn[N],cnt;
int sz[N],zz[N],top[N],fat[N],dep[N];
int s[N<<2],ad[N<<2];
int tot,head[N],to[M],nxt[M];
void add(int u,int v){
nxt[++tot]=head[u];
head[u]=tot;
to[tot]=v;
}
#define lc k<<1
#define rc k<<1|1
void addtag(int k,int l,int r,int d){
(ad[k]+=d)%=p;
(s[k]+=1ll*(r-l+1)*d%p)%=p;
}
void pushdown(int k,int l,int r,int mid){
if(!ad[k])return;
addtag(lc,l,mid,ad[k]);
addtag(rc,mid+1,r,ad[k]);
ad[k]=0;
}
void pushup(int k){
s[k]=(s[lc]+s[rc])%p;
}
void build(int k,int l,int r){
if(l==r){
read(s[k]);s[k]%=p;
return;
}
int mid=(l+r)>>1;
build(lc,l,mid);
build(rc,mid+1,r);
pushup(k);
}
void modify(int k,int l,int r,int x,int y,int w){
if(x<=l&&r<=y){
addtag(k,l,r,w);
return;
}
if(y<l||x>r)return;
int mid=(l+r)>>1;
pushdown(k,l,r,mid);
modify(lc,l,mid,x,y,w);
modify(rc,mid+1,r,x,y,w);
pushup(k);
}
int query(int k,int l,int r,int x,int y){
if(x<=l&&r<=y)return s[k];
if(l>y||r<x)return 0;
int mid=(l+r)>>1;
pushdown(k,l,r,mid);
return (query(lc,l,mid,x,y)+query(rc,mid+1,r,x,y))%p;
}
void dfs1(int u,int fa){
fat[u]=fa;
dep[u]=dep[fa]+1;
dfn[u]=++cnt;
sz[u]=1;
int w=0;
for(int i=head[u];i;i=nxt[i]){
int v=to[i];
if(v==fa)continue;
dfs1(v,u);
sz[u]+=sz[v];
if(!w||sz[v]>sz[w])w=v;
}
zz[u]=w;
}
void dfs2(int u,int t){
top[u]=t;
if(zz[u])dfs2(zz[u],t);
for(int i=head[u];i;i=nxt[i]){
int v=to[i];
if(v==fat[u]||v==zz[u])continue;
dfs2(v,v);
}
}
void modifyr(int u,int v,int w){
for(;top[u]!=top[v];){
if(dep[top[u]]<dep[top[v]])swap(u,v);
modify(1,1,n,dfn[top[u]],dfn[u],w);
u=fat[top[u]];
}
if(dep[u]>dep[v])swap(u,v);
modify(1,1,n,dfn[u],dfn[v],w);
}
int queryr(int u,int v){
int res=0;
for(;top[u]!=top[v];){
if(dep[top[u]]<dep[top[v]])swap(u,v);
(res+=query(1,1,n,dfn[top[u]],dfn[u]))%=p;
u=fat[top[u]];
}
if(dep[u]>dep[v])swap(u,v);
return (res+query(1,1,n,dfn[u],dfn[v]))%p;
}
int main(){
read(n,m,r,p);
build(1,1,n);
for(int i=1;i<n;++i){
read(u,v);
add(u,v);
add(v,u);
}
dfs1(r,0);
dfs2(r,r);
for(;m--;){
read(o);
if(o==1){
read(u,v,w);
modifyr(u,v,w);
}
else if(o==2){
read(u,v);
printf("%d\n",queryr(u,v));
}
else if(o==3){
read(u,w);
modify(1,1,n,dfn[u],dfn[u]+sz[u]-1,w);
}
else{
read(u);
printf("%d\n",query(1,1,n,dfn[u],dfn[u]+sz[u]-1));
}
}
return 0;
}
样例我输出
2
18