MnZn树剖板子37ptsRE求助

P3384 【模板】重链剖分/树链剖分

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 感谢!!已过


|