bnnnnn @ 2023-08-29 13:47:53
RT 原本怀疑是取模问题,但加了更多%并改long long 后仍RE orz
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long LL;
const LL maxn=2e5+5;
LL n,m,rt,mod;
LL head[maxn],to[maxn],nxt[maxn],w[maxn],wt[maxn],tot;
LL st[maxn<<2],laz[maxn<<2];
LL son[maxn],id[maxn],fa[maxn],dep[maxn],siz[maxn],top[maxn],cnt;
void add(LL u,LL v)
{
to[++tot]=v;
nxt[tot]=head[u];
head[u]=tot;
}
void dfs1(LL u,LL f,LL depth)
{
dep[u]=depth;
fa[u]=f;
siz[u]=1;
LL maxson=-1;
for(LL i=head[u];i;i=nxt[i])
{
LL v=to[i];
if(f==v) continue;
dfs1(v,u,depth+1);
siz[u]+=siz[v];
if(siz[v]>maxson) son[u]=v,maxson=siz[v];
}
}
void dfs2(LL u,LL ltp)
{
id[u]=++cnt;
wt[cnt]=w[u];
top[u]=ltp;
if(!son[u]) return;
dfs2(son[u],ltp);
for(LL i=head[u];i;i=nxt[i])
{
LL v=to[i];
if(v==fa[u]||v==son[u]) continue;
dfs2(v,v);
}
}
void pushup(LL now)
{
st[now]=(st[now<<1]+st[now<<1|1])%mod;
}
void pushdown(LL now,LL len)
{
laz[now]%=mod;
if(laz[now])
{
laz[now<<1]+=laz[now];
laz[now<<1|1]+=laz[now];
laz[now<<1]%=mod;
laz[now<<1|1]%=mod;
st[now<<1]+=laz[now]*(len-(len>>1))%mod;
st[now<<1|1]+=laz[now]*(len>>1)%mod;
st[now<<1]%=mod;
st[now<<1|1]%=mod;
laz[now]=0;
}
}
void build(LL now,LL l,LL r)
{
if(l==r)
{
st[now]=wt[l];
st[now]%=mod;
return;
}
LL mid=(l+r)>>1;
build(now<<1,l,mid);
build(now<<1|1,mid+1,r);
pushup(now);
}
void update(LL now,LL l,LL r,LL x,LL y,LL z)
{
if(x<=l&&r<=y)
{
laz[now]+=z%mod;
laz[now]%=mod;
st[now]+=z*((r-l+1)%mod)%mod;
st[now]%=mod;
return;
}
pushdown(now,r-l+1);
LL mid=(l+r)>>1;
if(x<=mid) update(now<<1,l,mid,x,y,z);
if(y>mid) update(now<<1|1,mid+1,r,x,y,z);
pushup(now);
}
LL query(LL now,LL l,LL r,LL x,LL y)
{
if(x<=l&&r<=y) return st[now]%mod;
pushdown(now,r-l+1);
LL ans=0;
LL mid=(l+r)>>1;
if(x<=mid) ans+=query(now<<1,l,mid,x,y)%mod;
ans%=mod;
if(y>mid) ans+=query(now<<1|1,mid+1,r,x,y)%mod;
ans%=mod;
return ans;
}
void updRange(LL x,LL y,LL z)
{
z%=mod;
while(top[x]!=top[y])
{
if(dep[top[x]]<dep[top[y]]) swap(x,y);
update(1,1,n,id[top[x]],id[x],z);
x=fa[top[x]];
}
if(dep[x]>dep[y]) swap(x,y);
update(1,1,n,id[x],id[y],z);
}
LL qRange(LL x,LL y)
{
LL ans=0;
while(top[x]!=top[y])
{
if(dep[top[x]<dep[top[y]]]) swap(x,y);
ans+=query(1,1,n,id[top[x]],id[x])%mod;
ans%=mod;
x=fa[top[x]];
}
if(dep[x]>dep[y]) swap(x,y);
ans+=query(1,1,n,id[x],id[y])%mod;
ans%=mod;
return ans;
}
void updSon(LL x,LL y)
{
update(1,1,n,id[x],id[x]+siz[x]-1,y);
}
LL qSon(LL x)
{
return query(1,1,n,id[x],id[x]+siz[x]-1)%mod;
}
int main()
{
scanf("%lld%lld%lld%lld",&n,&m,&rt,&mod);
for(LL i=1;i<=n;i++) scanf("%lld",&w[i]);
for(LL i=1;i<n;i++)
{
LL u,v;
scanf("%lld%lld",&u,&v);
add(u,v); add(v,u);
}
dfs1(rt,0,1);
dfs2(rt,rt);
build(1,1,n);
while(m--)
{
LL opt,x,y,z;
scanf("%lld",&opt);
switch(opt)
{
case 1:
scanf("%lld%lld%lld",&x,&y,&z);
updRange(x,y,z%mod);
break;
case 2:
scanf("%lld%lld",&x,&y);
printf("%lld\n",qRange(x,y));
break;
case 3:
scanf("%lld%lld",&x,&y);
updSon(x,y%mod);
break;
case 4:
scanf("%lld",&x);
printf("%lld\n",qSon(x));
break;
}
}
return 0;
}
by Jonny09 @ 2023-08-29 14:54:09
@bnnnnn qrange函数里的中括号位置写错了
by Jonny09 @ 2023-08-29 14:54:47
if(dep[top[x]<dep[top[y]]]) swap(x,y);
by bnnnnn @ 2023-08-31 20:38:48
@Jonny09 感谢!!已过