社区讨论

10分树剖,求义父调,悬赏一关注

P3384【模板】重链剖分 / 树链剖分参与者 2已保存回复 9

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
9 条
当前快照
1 份
快照标识符
@lo1vnc9i
此快照首次捕获于
2023/10/23 03:44
2 年前
此快照最后确认于
2023/11/03 04:13
2 年前
查看原帖
CPP
#include<bits/stdc++.h>
#define N 200086
#define mid ((l+r)>>1)
using namespace std;
int head[N],to[N*2],nex[N*2],tot;
int n,m,r,p;
void add(int u,int v){
    to[++tot]=v;
    nex[tot]=head[u];
    head[u]=tot;
}
int a[N],lazy[N],wt[N];
void build(int x,int l,int r){
    if(l==r){
        a[x]=wt[x];
        if(a[x]>p)a[x]%=p;
        return ;
    }
    build(x<<1,l,mid);
    build(x<<1|1,mid+1,r);
    a[x]=(a[x<<1]+a[x<<1|1])%p;
}
void pushdown(int x,int len){
    lazy[x<<1]+=lazy[x];
    lazy[x<<1|1]+=lazy[x];
    a[x<<1]+=lazy[x]*(len-(len>>1));
    a[x<<1]%=p;
    a[x<<1|1]+=lazy[x]*(len>>1);
    a[x<<1|1]%=p;
    lazy[x]=0;
}
int res;
void query(int x,int l,int r,int L,int R){
    if(L<=l&&R>=r){
        res+=a[x];
        res%=p;
        return;
    }
    else{
        if(lazy[x])pushdown(x,r-l+1);
        if(L<=mid)query(x<<1,l,mid,L,R);
        if(R>mid)query(x<<1|1,mid+1,r,L,R);
    }
}
void update(int x,int k,int l,int r,int L,int R){
    if(L<=l&&R>=r){
        lazy[x]+=k;
        a[x]+=k*(r-l+1);
    }
    else{
        if(lazy[x])pushdown(x,r-l+1);
        if(L<=mid)update(x<<1,k,l,mid,L,R);
        if(R>mid)update(x<<1|1,k,mid+1,r,L,R);
        a[x]=(a[x<<1]+a[x<<1|1])%p;
    }
}
int dep[N],fa[N],sonsize[N],son[N];
void dfs1(int x,int f,int deep){
    fa[x]=f;
    dep[x]=deep;
    sonsize[x]=1;
    int maxson=-1;
    for(int i=head[x];i;i=nex[i]){
        if(to[i]==f)continue;
        dfs1(to[i],x,deep+1);
        sonsize[x]+=sonsize[to[i]];
        if(maxson<sonsize[to[i]]){
            maxson=sonsize[to[i]];
            son[x]=to[i];
        }
    }
}
int top[N],id[N],cnt,w[N];
void dfs2(int x,int topf){
    id[x]=++cnt;
    top[cnt]=topf;
    w[cnt]=wt[x];
    if(!son[x])return ;
    dfs2(son[x],topf);
    for(int i=head[x];i;i=nex[i]){
        if(to[i]==son[x]||to[i]==fa[x])continue;
        dfs2(to[i],to[i]);
    }
}
int qSon(int x){
    res=0;
    query(1,1,n,id[x],id[x]+sonsize[x]-1);
    return res;
}
void rSon(int x,int k){
    update(1,k,1,n,id[x],id[x]+sonsize[x]-1);
}
int range(int x,int y){
    int ans=0;
    while(top[x]!=top[y]){
        if(dep[top[x]]<dep[top[y]])swap(x,y);
        res=0;
        query(1,1,n,id[top[x]],id[x]);
        ans+=res;
        ans%=p;
        x=fa[top[x]];
    }
    if(dep[x]>dep[y])swap(x,y);
    res=0;
    query(1,1,n,id[x],id[y]);
    ans+=res;
    ans%=p;
    return ans;
}
void up_date(int x,int y,int k){
    k%=p;
    while(top[x]!=top[y]){
        if(dep[top[x]]<dep[top[y]])swap(x,y);
        update(1,k,1,n,id[top[x]],id[x]);
        x=fa[top[x]];
    }
    if(dep[x]>dep[y])swap(x,y);
    update(1,k,1,n,id[x],id[y]);
}
int main(){
    cin>>n>>m>>r>>p;
    int x,y,z,B;
    for(int i=1;i<=n;i++)cin>>wt[i];
    for(int i=1;i<n;i++){
        cin>>x>>y;
        add(x,y);
        add(y,x);
    }
    dfs1(r,0,1);
    dfs2(r,r);
    build(1,1,n);
    for(int i=1;i<=m;i++){
        cin>>B;
        if(B==1){
            cin>>x>>y>>z;
            up_date(x,y,z);
        }
        if(B==2){
            cin>>x>>y;
            cout<<range(x,y)<<"\n";
        }
        if(B==3){
            cin>>x>>y;
            rSon(x,y);
        }
        if(B==4){
            cin>>x;
            cout<<qSon(x)<<"\n";
        }
    }
    return 0;
}

回复

9 条回复,欢迎继续交流。

正在加载回复...