WA,求助

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

yezerui11 @ 2022-12-29 19:55:20

#include<bits/stdc++.h>
using namespace std;
#define ull long long
ull fa[500010];//
ull tp[500010];//
ull dep[500010];//
ull a[500010];//
ull flag[500010];//
ull Siz[500010];//
ull dfn[500010];//
ull fdn[500010];//
ull now;//
ull n,m,R,P;//
struct node{
    ull l,r,tag,sum;
}p[500010];
ull siz(ull x){
    return p[x].r-p[x].l+1;
}
void pushup(ull x){
    p[x].sum=(p[2*x].sum+p[2*x+1].sum)%P;
}
void pushdown(ull x){
    if(!p[x].tag)return;
    ull tag=p[x].tag;
    ull lc=2*x,rc=2*x+1;
    p[lc].sum=(p[lc].sum+tag*siz(lc))%P;
    p[rc].sum=(p[rc].sum+tag*siz(rc))%P;
    p[lc].tag+=tag;
    p[rc].tag+=tag;
    p[lc].tag%=P;
    p[rc].tag%=P;
    p[x].tag=0;
}
void creat(ull x,ull l,ull r){
    if(l>r)swap(l,r);
    p[x].l=l;
    p[x].r=r;
    if(l==r){
        p[x].sum=a[fdn[l]]%P;
        return;
    }
    ull mid=(l+r)/2;
    creat(2*x,l,mid);
    creat(2*x+1,mid+1,r);
    pushup(x);
}
void change(ull x,ull k,ull l,ull r){
    if(l>r)swap(l,r);
    if(p[x].l>r||p[x].r<l)return;
    if(p[x].l>=l&&p[x].r<=r){
        p[x].tag+=k;
        p[x].sum+=k*siz(x);
        p[x].tag%=P;
        p[x].sum%=P;
        return;
    }
    pushdown(x);
    change(2*x,k,l,r);
    change(2*x+1,k,l,r);
    pushup(x);
}
ull query(ull x,ull l,ull r){
    if(l>r)swap(l,r);
    if(p[x].l>r||p[x].r<l)return 0;
    if(l<=p[x].l&&p[x].r<=r){
        return p[x].sum%P;
    }
    pushdown(x);
    return (query(2*x,l,r)+query(2*x+1,l,r))%P;
}
vector<int>e[500010];
void dfs1(int u,int f){
    Siz[u]=1;
    for(int i=0;i<e[u].size();i++){
        int v=e[u][i];
        if(v!=f){
            dfs1(v,u);
            Siz[u]+=Siz[v];
        }
    }
}
void dfs2(int u,int f){
    dfn[u]=++now;
    fdn[now]=u;
    int f1=dfn[f],u1=dfn[u];
    dep[u1]=dep[f1]+1;
    if(!flag[u]){
        tp[u1]=u1;
    }else{
        tp[u1]=tp[f1];
    }
    fa[u1]=f1;
    int mx=0,k=0;
    for(int i=0;i<e[u].size();i++){
        int v=e[u][i];
        if(v!=f&&Siz[v]>mx){
            k=v;
            mx=Siz[v];
        }
    }
    flag[k]=1;
    for(int i=0;i<e[u].size();i++){
        int v=e[u][i];
        if(v!=f){
            dfs2(v,u);
        }
    }
}
int main(){
    cin>>n>>m>>R>>P;
    for(int i=1;i<=n;i++){
        cin>>a[i];
        a[i]%=P;
    }
    for(int i=1;i<n;i++){
        int u,v;
        cin>>u>>v;
        e[u].push_back(v);
        e[v].push_back(u);
    }
    dfs1(R,0);
    dfs2(R,0);
    creat(1,1,n);
    while(m--){
        int k=0,u=0,v=0,z=0;
        cin>>k>>u;
        if(k==1){
            cin>>v>>z;
        }else if(k==2){
            cin>>v;
        }else if(k==3){
            cin>>z;
        }

        u=dfn[u];
        v=dfn[v];
        z%=P;

        if(k==1){
            while(tp[u]!=tp[v]){
                if(dep[tp[u]]<dep[tp[v]]){
                    swap(u,v);
                }
                change(1,z,tp[u],u);
                u=fa[tp[u]];
            }
            if(dep[u]>dep[v]){
                swap(u,v);
            }
            change(1,z,u,v);
        }
        if(k==2){
            int sum=0;
            while(tp[u]!=tp[v]){
                if(dep[tp[u]]<dep[tp[v]]){
                    swap(u,v);
                }
                sum=(sum+query(1,tp[u],u))%P;
                u=fa[tp[u]];
            }
            if(dep[u]>dep[v]){
                swap(u,v);
            }
            sum=(sum+query(1,u,v))%P;
            cout<<sum<<endl;
        }
        if(k==3){
            change(1,z,u,u+Siz[fdn[u]]-1);
        }
        if(k==4){
            cout<<query(1,u,u+Siz[fdn[u]]-1)<<endl;
        }
    }
    return 0;
}

rt,提交记录

悬赏1关注


|