RE 10pts 求助

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

CR400BFAZ5254 @ 2024-07-16 15:36:31

#include<bits/stdc++.h>
#define MAXN 200010
#define lson (rt<<1)
#define rson ((rt<<1)|1)
using namespace std;
typedef long long ll;
ll n,m,r,p;
ll a[MAXN];
ll fa[MAXN],dep[MAXN],siz[MAXN],son[MAXN];
ll top[MAXN],dfn[MAXN],rnk[MAXN],id;
ll sum[MAXN<<2],add[MAXN<<2];
vector<int> e[MAXN];
void addedge(int x,int y){
    e[x].push_back(y);
    e[y].push_back(x);
}
void dfs1(int u,int p=0){
    fa[u]=p;
    dep[u]=dep[p]+1;
    siz[u]=1;
    son[u]=0;
    for(auto v:e[u]){
        if(v!=p){
            dfs1(v,u);
            siz[u]+=siz[v];
            if(siz[v]>siz[son[u]]){
                son[u]=v;
            }
        }
    }
}
void dfs2(int u,int t){
    top[u]=t;
    dfn[u]=++id;
    rnk[id]=u;
    if(!son[u]) return ;
    dfs2(son[u],t);
    for(auto v:e[u]){
        if(v!=fa[u]&&v!=son[u]) dfs2(v,v);
    }
}
void build(int l,int r,int rt){
    if(l==r){
        sum[rt]=a[rnk[l]]%p;
        return ;
    }
    int mid=(l+r)>>1;
    build(l,mid,rt<<1);
    build(mid+1,r,rt<<1|1);
    sum[rt]=(sum[rt<<1]+sum[rt<<1|1])%p;
}
void push_color(int l,int r,int rt){
    if(!add[rt]) return ;
    int mid=(l+r)>>1;
    add[rt<<1]+=add[rt];
    sum[rt<<1]+=(ll)(mid-l+1)*add[rt];
    add[rt<<1|1]+=add[rt];
    sum[rt<<1|1]+=(ll)(r-mid)*sum[rt];
    add[rt<<1]%=p;
    add[rt<<1|1]%=p;
    sum[lson]%=p;
    sum[rson]%=p;
    add[rt]=0;
}
void update(int lp,int rp,int rt,int l,int r,int k){
    if(l<=lp&&rp<=r){
        add[rt]+=k;add[rt]%=p;
        sum[rt]+=(ll)(r-l+1)*k;
        sum[rt]%=p;
        return ;
    }
    push_color(l,r,rt);
    int mid=(l+r)>>1;
    if(l<=mid) update(lp,mid,lson,l,r,k);
    if(r>mid) update(mid+1,rp,rson,l,r,k);
    sum[rt]=(sum[lson]+sum[rson])%p;
}
ll query(int lp,int rp,int rt,int l,int r){
    ll s=0;
    if(l<=lp&&rp<=r) return sum[rt]%p;
    push_color(lp,rp,rt);
    int mid=(l+r)>>1;
    if(l<=mid) s=(s+query(lp,mid,lson,l,r))%p;
    if(r>mid) s=(s+query(mid+1,r,rson,l,r))%p;
    return s;
}
void update_son(ll x,ll v){
    update(1,n,1,dfn[x],dfn[x]+siz[x]-1,v);
}
ll query_son(ll x){
    return query(1,n,1,dfn[x],dfn[x]+siz[x]-1);
}
void update_chain(ll x,ll y,ll v){
    while(top[x]!=top[y]){
        if(dep[top[x]]<dep[top[y]]) swap(x,y);
        update(1,n,1,dfn[top[x]],dfn[top[y]],v);
        x=fa[top[x]];
    }
    if(dep[x]>dep[y]) swap(x,y);
    update(1,n,1,dfn[x],dfn[y],v);
}
ll query_chain(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,n,1,dfn[top[x]],dfn[x]);
        ans%=p;
        x=fa[top[x]];
    }
    if(dep[x]>dep[y]) swap(x,y);
    ans+=query(1,n,1,dfn[x],dfn[y]);
    ans%=p;
    return ans;
}
int main(){
    scanf("%d%d%d%lld",&n,&m,&r,&p);
    for(int i=1;i<=n;i++) scanf("%d",&a[i]);
    for(int i=1;i<=n-1;i++){
        int x,y;
        scanf("%d%d",&x,&y);
        addedge(x,y);
    }
    dfs1(r);
    dfs2(r,r);
    build(1,n,1);
    while(m--){
        int op,x,y,z;
        scanf("%d",&op);
        if(op==1){
            scanf("%d%d%d",&x,&y,&z);
            update_chain(x,y,z%p);
        }else if(op==2){
            scanf("%d%d",&x,&y);
            printf("%lld\n",query_chain(x,y)%p);
        }else if(op==3){
            scanf("%d%d",&x,&y);
            update_son(x,y%p);
        }else{
            scanf("%d",&x);
            printf("%lld\n",query_son(x)%p);
        }
    }

    return 0;
}

by jianhe @ 2024-09-08 13:29:10

@CR400BFAZ5254

update_chain 函数里的

update(1,n,1,dfn[top[x]],dfn[top[y]],v);

是不是应该写成 update(1,n,1,dfn[top[x]],dfn[x],v);


by CR400BFAZ5254 @ 2024-09-08 13:37:03

@jianhe 还是挂


by jianhe @ 2024-09-18 20:58:19

@CR400BFAZ5254 push_color

sum[rt<<1|1]+=(ll)(r-mid)*sum[rt];

写错了


by CR400BFAZ5254 @ 2024-09-18 21:02:27

依然改变不了RE的事实


|