#1,2,3,11 AC,其余 WA。
下载测试结果后发现对于 3,4 操作无误,1,2 操作有误。但是不知道哪里出了问题。
#include<bits/stdc++.h>
#define int long long
#define N 100005
using namespace std;
struct Data{int l,r,sum,tag;}t[N*4];
int n,m,s,cnt,mod;
int a[N],fa[N],sz[N],dep[N],dfn[N],wc[N],top[N],vis[N];
vector<int>v[N];
void maketag(int k,int s)
{
t[k].sum=(t[k].sum+s*(t[k].r-t[k].l+1)%mod)%mod;
t[k].tag=(t[k].tag+s)%mod;
return;
}
void pushdown(int k)
{
maketag(k*2,t[k].tag);
maketag(k*2+1,t[k].tag);
t[k].tag=0;
return;
}
void build(int k,int l,int r)
{
t[k].l=l,t[k].r=r;
if(t[k].l==t[k].r)
{
t[k].sum=a[vis[l]]%mod;
return;
}
int mid=l+r>>1;
build(k*2,l,mid);
build(k*2+1,mid+1,r);
t[k].sum=(t[k*2].sum+t[k*2+1].sum)%mod;
return;
}
void update(int k,int l,int r,int x)
{
if(l<=t[k].l&&r>=t[k].r)
{
maketag(k,x);
return;
}
pushdown(k);
int mid=t[k].l+t[k].r>>1;
if(l<=mid) update(k*2,l,r,x);
if(r>mid) update(k*2+1,l,r,x);
t[k].sum=(t[k*2].sum+t[k*2+1].sum)%mod;
return;
}
int query(int k,int l,int r)
{
if(l<=t[k].l&&r>=t[k].r) return t[k].sum%mod;
pushdown(k);
int mid=t[k].l+t[k].r>>1,ans=0;
if(l<=mid) ans=(ans+query(k*2,l,r))%mod;
if(r>mid) ans=(ans+query(k*2+1,l,r))%mod;
return ans;
}
void dfs1(int k,int f)
{
dep[k]=dep[f]+1;
sz[k]=1;
fa[k]=f;
for(int now:v[k])
{
if(now==f) continue;
dfs1(now,k);
sz[k]+=sz[now];
if(sz[now]>sz[wc[k]]) wc[k]=now;
}
return;
}
void dfs2(int k,int Top)
{
dfn[k]=++cnt;
vis[cnt]=k;
top[k]=Top;
if(wc[k]) dfs2(wc[k],Top);
for(int now:v[k])
{
if(now==fa[k]||now==wc[k]) continue;
dfs2(now,now);
}
return;
}
void upd(int x,int y,int z)
{
while(top[x]!=top[y])
{
if(dep[x]<dep[y]) swap(x,y);
update(1,dfn[top[x]],dfn[x],z);
x=fa[top[x]];
}
if(dep[x]>dep[y]) swap(x,y);
update(1,dfn[x],dfn[y],z);
return;
}
int qry(int x,int y)
{
int res=0;
while(top[x]!=top[y])
{
if(dep[x]<dep[y]) swap(x,y);
res=(res+query(1,dfn[top[x]],dfn[x]))%mod;
x=fa[top[x]];
}
if(dep[x]>dep[y]) swap(x,y);
res=(res+query(1,dfn[x],dfn[y]))%mod;
return res;
}
signed main()
{
ios::sync_with_stdio(0);
cin>>n>>m>>s>>mod;
for(int i=1;i<=n;i++) cin>>a[i];
for(int i=1;i<n;i++)
{
int x,y;
cin>>x>>y;
v[x].push_back(y);
v[y].push_back(x);
}
dfs1(s,0);
dfs2(s,0);
build(1,1,n);
while(m--)
{
int op,x,y,z;
cin>>op;
if(op==1) cin>>x>>y>>z,upd(x,y,z%mod);
if(op==2) cin>>x>>y,cout<<qry(x,y)%mod<<"\n";
if(op==3) cin>>x>>y,update(1,dfn[x],dfn[x]+sz[x]-1,y%mod);
if(op==4) cin>>x,cout<<query(1,dfn[x],dfn[x]+sz[x]-1)%mod<<"\n";
}
return 0;
}