树剖过不了样例求助

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

Dino_chx @ 2023-08-13 10:31:32

这个是跟着日报学的树剖,但是不知道为什么过不了样例,求助qwq


#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N=1e5+7;
vector<int> e[N];
int n,m,root,P,a[N],fa[N],d[N],siz[N],son[N],rk[N],top[N],dfn[N],thistime;
struct Segment_Tree
{
    struct maintain
    {
        int l,r;
        ll sum,tag;
    }tree[N<<2];
    void pushup(int x)
    {
        tree[x].sum=(tree[x<<1].sum+tree[x<<1|1].sum)%P;
        return;
    }
    void build(int x,int l,int r)
    {
        tree[x]={l,r};
        if(l==r)
        {
            tree[x].sum=a[rk[l]]%P;
            return;
        }
        int mid=l+r>>1;
        build(x<<1,l,mid);
        build(x<<1|1,mid+1,r);
        pushup(x);
        return;
    }
    void pushdown(int x)
    {
        maintain &rt=tree[x],&ls=tree[x<<1],&rs=tree[x<<1|1];
        if(rt.tag)
        {
            ls.tag=(ls.tag+rt.tag)%P;
            rs.tag=(rs.tag+rt.tag)%P;
            ls.sum=(ls.sum+(ls.r-ls.l+1)*rt.tag%P)%P;
            rs.sum=(ls.sum+(rs.r-rs.l+1)*rt.tag%P)%P;
            rt.tag=0;
        }
        return;
    }
    void update(int x,int l,int r,int k)
    {
        if(l<=tree[x].l&&r>=tree[x].r)
        {
            tree[x].sum=(tree[x].sum+(tree[x].r-tree[x].l+1)*k%P)%P;
            tree[x].tag=(tree[x].tag+k)%P;
            return;
        }
        pushdown(x);
        int mid=tree[x].l+tree[x].r>>1;
        if(l<=mid)
            update(x<<1,l,r,k);
        if(r>mid)
            update(x<<1|1,l,r,k);
        pushup(x);
        return;
    }
    ll query(int x,int l,int r)
    {
        if(l<=tree[x].l&&r>=tree[x].r)
            return tree[x].sum%P;
        pushdown(x);
        int mid=tree[x].l+tree[x].r>>1;
        ll res=0;
        if(l<=mid)
            res=(res+query(x<<1,l,r))%P;
        if(r>mid)
            res=(res+query(x<<1|1,l,r))%P;
        return res%P;       
    }
}tree;
void dfs1(int x,int Fa)
{
    fa[x]=Fa;
    siz[x]=1;
    d[x]=d[Fa]+1;
    for(auto it:e[x])
    {
        if(it!=Fa)
        {
            dfs1(it,x);
            siz[x]+=siz[it];
            if(siz[it]>siz[son[x]])
                son[x]=it;
        }
    }
    return;
}
void dfs2(int x,int tp)
{
    top[x]=tp;
    dfn[x]=++thistime;
    rk[thistime]=x;
    if(!son[x])
        return;
    dfs2(son[x],tp);
    for(auto it:e[x])
    {
        if(it!=son[x]&&it!=fa[x])
            dfs2(it,it);
    }
    return;
}
ll query_edge(int x,int y)
{
    int fx=top[x],fy=top[y];
    ll res=0;
    while(fx!=fy)
    {
        if(d[fx]>=d[fy])
        {
            res=(res+tree.query(1,dfn[fx],dfn[x]))%P;
            x=fa[fx];
            fx=top[x];
        }
        else
        {
            res=(res+tree.query(1,dfn[fy],dfn[y]))%P;
            y=fa[fy];
            fy=top[y];
        }
    }
    if(dfn[x]<=dfn[y])
        res=(res+tree.query(1,dfn[x],dfn[y]))%P;
    else
        res=(res+tree.query(1,dfn[y],dfn[x]))%P;
    return res%P;
}
void update_edge(int x,int y,int c)
{
    int fx=top[x],fy=top[y];
    while(fx!=fy)
    {
        if(d[fx]>=d[fy])
        {
            tree.update(1,dfn[fx],dfn[x],c);
            x=fa[fx];
            fx=top[x];
        }
        else
        {
            tree.update(1,dfn[fy],dfn[y],c);
            y=fa[fy];
            fy=top[y];
        }
    }
    if(dfn[x]<=dfn[y])
        tree.update(1,dfn[x],dfn[y],c);
    else
        tree.update(1,dfn[y],dfn[x],c);
    return;
}
int main()
{
    scanf("%d%d%d%d",&n,&m,&root,&P);
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&a[i]);
    }
    for(int i=1,u,v;i<n;i++)
    {
        scanf("%d%d",&u,&v);
        e[u].push_back(v);
        e[v].push_back(u);
    }
    d[root]=1;
    dfs1(root,0);
    dfs2(root,root);
    tree.build(1,1,n);
    while(m--)
    {
        int op,x,y,z;
        scanf("%d",&op);
        if(op==1)
        {
            scanf("%d%d%d",&x,&y,&z);
            update_edge(x,y,z);
        }
        if(op==2)
        {
            scanf("%d%d",&x,&y);
            printf("%lld\n",query_edge(x,y));
        }
        if(op==3)
        {
            scanf("%d%d",&x,&z);
            tree.update(1,dfn[x],dfn[x]+siz[x]-1,z);
        }
        if(op==4)
        {
            scanf("%d",&x);
            printf("%lld\n",tree.query(1,dfn[x],dfn[x]+siz[x]-1));
        }
    }
    return 0;
}

by ax_by_c @ 2023-08-13 10:34:15

这边建议花个半小时重新打一遍

其实是死因和我不一样


by liuxy1234 @ 2023-08-13 10:37:06

可以把树剖和线段树拆开调试试试


by ax_by_c @ 2023-08-13 11:07:01

调完了

死因:第41行的rs打成了ls


by ax_by_c @ 2023-08-13 11:07:28

哈哈哈线段树寄了


by ax_by_c @ 2023-08-13 11:07:48

啸死我了


by Dino_chx @ 2023-08-14 08:08:25

过了,谢谢

此贴结


by yanjiadong @ 2024-08-25 10:18:54

啸死了时隔多年我没调用dfs1dfs2build


|