h吼吼吼吼吼吼吼吼吼吼吼吼吼吼吼哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈吼吼吼吼吼吼吼吼吼吼吼吼吼吼吼和
11哈哈哈哈哈哈哈哈哈哈,哈哈
哈哈哈,,哈哈哈哈
吼吼吼吼吼吼吼吼吼吼吼吼吼吼吼
#include<cstdio> #define N 100002 #define ls(A) ((A)<<1) #define rs(A) ((A)<<1|1) int n,m,t1,t2,t3; int val[N],tree[N<<2],dep[N],f[N],sz[N],son[N],top[N],y[N],id[N]; int head[N],tot,num,MOD,R; int tag[N<<1]; \\fgfasgaga struct Edge { int next,to; }e[N<<1]; inline void Add(int A,int B) { e[++tot].next=head[A]; e[tot].to=B; head[A]=tot; } int tmp; inline void Swap(int &A,int &B){tmp=A;A=B;B=tmp;} inline int Read() { int X=0,F=1;char C='?'; while(C>'9'||C<'0')F=(C=='-')?-1:1,C=getchar(); while(C<='9'&&C>='0')X=(X<<3)+(X<<1)+(C^48),C=getchar(); return X*F; } inline void pushup(int p) { tree[p]=(tree[ls(p)]+tree[rs(p)])%MOD; } void Build(int p,int l,int r) { if(l==r) { tree[p]=y[l]; return; } int mid=(l+r)>>1; Build(ls(p),l,mid); Build(rs(p),mid+1,r); pushup(p); } inline void Add2(int p,int l,int r,int v) { tag[p]+=v; tree[p]+=(r-l+1)*v; tree[p]%=MOD; } inline void pushdown(int p,int l,int r,int mid) { if(l==r||tag[p]==0) { tag[p]=0;return; } Add2(ls(p),l,mid,tag[p]); Add2(rs(p),mid+1,r,tag[p]); tag[p]=0; } void change(int p,int l,int r,int x,int y,int v) { if(x<=l&&r<=y) return Add2(p,l,r,v); int mid=(l+r)>>1; pushdown(p,l,r,mid); if(x<=mid) change(ls(p),l,mid,x,y,v); if(mid<y) change(rs(p),mid+1,r,x,y,v); pushup(p); } int query(int p,int l,int r,int x,int y) { if(x<=l&&r<=y) return tree[p]; int mid=(l+r)>>1,res=0; pushdown(p,l,r,mid); if(x<=mid) res=(res+query(ls(p),l,mid,x,y))%MOD; if(mid<y) res=(res+query(rs(p),mid+1,r,x,y))%MOD; return res; } void dfs1(int p,int fa) { f[p]=fa;dep[p]=dep[fa]+1;sz[p]=1; for(int i=head[p];i;i=e[i].next) { if(e[i].to!=fa) { dfs1(e[i].to,p); sz[p]+=sz[e[i].to]; if(sz[e[i].to]>sz[son[p]]) son[p]=e[i].to; } } } void dfs2(int p,int t) { top[p]=t;id[p]=++num;y[num]=val[p];// if(!son[p]) return; dfs2(son[p],t); for(int i=head[p];i;i=e[i].next) { if(e[i].to!=f[p]&&e[i].to!=son[p]) { dfs2(e[i].to,e[i].to); } } } void range(int x,int y,int v) { v%=MOD; while(top[x]!=top[y]) { if(dep[top[x]]<dep[top[y]]) Swap(x,y); change(1,1,n,id[top[x]],id[x],v); x=f[top[x]]; } if(dep[x]>dep[y]) Swap(x,y); change(1,1,n,id[x],id[y],v); } int AskR(int x,int y) { int res=0; while(top[x]!=top[y]) { if(dep[top[x]]<dep[top[y]]) Swap(x,y); res=(res+query(1,1,n,id[top[x]],id[x]))%MOD; x=f[top[x]]; } if(dep[x]>dep[y]) Swap(x,y); res+=query(1,1,n,id[x],id[y]); return res%MOD; } signed main() { n=Read();m=Read();R=Read();MOD=Read(); for(int i=1;i<=n;i++) val[i]=Read(); for(int i=1;i<n;i++) { t1=Read();t2=Read(); Add(t1,t2);Add(t2,t1); } dfs1(R,0);dfs2(R,R); Build(1,1,n); while(m--) { t1=Read(); if(t1==1) { t1=Read();t2=Read();t3=Read(); range(t1,t2,t3); } else if(t1==2) { t1=Read();t2=Read(); printf("%d\n",AskR(t1,t2)); } else if(t1==3) { t1=Read();t2=Read(); change(1,1,n,id[t1],id[t1]+sz[t1]-1,t2); } else { t1=Read(); printf("%d\n",query(1,1,n,id[t1],id[t1]+sz[t1]-1)); } } }