1-10re求调

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

kisuti @ 2023-11-09 10:24:37

#include<bits/stdc++.h>
using namespace std;
inline int rd(){
    int x=0;
    char ch=getchar();
    bool flag=true;
    while(!isdigit(ch)){
        if(ch=='-')flag=false;
        ch=getchar();
    }
    while(isdigit(ch)){
        x=(x<<1)+(x<<3)+ch-'0';
        ch=getchar();
    }
    if(flag)return x;
    return ~(x-1);
}
long long  n,m,r,p,cnt=0,idx=0;
long long res=0;
int fa[200010],e[200010],ne[200010],h[200010];
long long si[200010],dep[200010],son[200010],w[200010],wt[200010],top[200010],id[200010];
struct node{
    long long val,tag;
    int sz;
}shu[4000010];
void update(int id){shu[id].val=(shu[id<<1].val%p+shu[id<<1|1].val%p)%p;}
void build(int id,int l,int r){
    shu[id].sz=r-l+1;
    shu[id].tag=0;
    if(l==r)shu[id].val=wt[l]%p;
    else{
        int mid=(l+r)>>1;
        build(id<<1,l,mid);
        build(id<<1|1,mid+1,r);
        update(id);
    }
}
void settag(int id,int tag){
    shu[id].val+=tag*shu[id].sz%p;
    shu[id].tag+=tag;
    shu[id].val=shu[id].val%p;
}
void pushdown(int id){
    settag(id<<1,shu[id].tag);
    settag(id<<1|1,shu[id].tag);
    shu[id].tag=0;
}
void mutify(int id,int l,int r,int ql,int qr,int k){
    if(ql==l&&qr==r){
        settag(id,k);
        return;
    }
    pushdown(id);
    int mid=(l+r)>>1;
    if(qr<=mid)mutify(id<<1,l,mid,ql,qr,k);
    else if(ql>mid)mutify(id<<1|1,mid+1,r,ql,qr,k);
    else {
        mutify(id<<1,l,mid,ql,mid,k);
        mutify(id<<1|1,mid+1,r,mid+1,qr,k);
    }
    update(id);
}
long long que(int id,int l,int r,int ql,int qr){
    if(l==ql&&r==qr)return shu[id].val%p;
    pushdown(id);
    int mid=(l+r)>>1;
    if(qr<=mid)return que(id<<1,l,mid,ql,qr)%p;
    else if(ql>mid)return que(id<<1|1,mid+1,r,ql,qr)%p;
    else return (que(id<<1,l,mid,ql,mid)%p+que(id<<1|1,mid+1,r,mid+1,qr)%p)%p;
}
void add(int a, int b){e[++idx] = b, ne[idx] = h[a], h[a] = idx ;}
void dfs1(int u,int z,int d){
    fa[u]=z,dep[u]=d,si[u]=1;
    for(int i=h[i];i;i=ne[i]){
        int o=e[i];
        if(o==z)continue;
        dfs1(o,u,d+1);
        si[u]+=si[o];
        if(si[o]>si[son[u]])son[u]=o;
    }
}
void dfs2(int u,int topf){
    id[u]=++cnt;
    wt[cnt]=w[u]%p;
    top[u]=topf;
    if(!son[u])return;
    dfs2(son[u],topf);
    for(int i=h[u];i;i=ne[i]){
        int o=e[i];
        if(o==son[u]||o==fa[u])continue;
        dfs2(o,o);
    }
}
void update_path(int x,int y,int z){
    z%=p;
    while(top[x]!=top[y]){
        if(dep[top[x]]<dep[top[y]])swap(x,y);
        mutify(1,1,n,id[top[x]],id[x],z);
        x=fa[top[x]];
    }
    if(dep[x]>dep[y])swap(x,y);
    mutify(1,1,n,id[x],id[y],z);
}
long long que_path(int x,int y){
    res=0;
    while(top[x]!=top[y]){
        if(dep[top[x]]<dep[top[y]])swap(x,y);
        res=(res%p+que(1,1,n,id[top[x]],id[x])%p)%p;
        x=fa[top[x]];
    }
    if(dep[x]>dep[y])swap(x,y);
    res=(res%p+que(1,1,n,id[x],id[y])%p)%p;
    return res%p;
}
void update_tree(int x,int k){
    mutify(1,1,n,id[x],id[x]+si[x]-1,k);
}
long long que_tree(int x){
    res=que(1,1,n,id[x],id[x]+si[x]-1)%p;
    return res;
}
int main(){
    n=rd(),m=rd(),r=rd(),p=rd();
    for(int i=1;i<=n;i++){w[i]=rd();}
    for(int i=1;i<=n-1;i++){
        int x=rd(),y=rd();
        add(x,y);
        add(y,x);
    }
    dfs1(r,0,1);
    dfs2(r,r);
    build(1,1,n);
    while(m--){
        int opt=rd();
        if(opt==1){
            int x=rd(),y=rd(),z=rd();
            update_path(x,y,z);
        }
        if(opt==2){
            int x=rd(),y=rd();
            printf("%d\n",que_path(x,y));
        }
        if(opt==3){
            int x=rd(),z=rd();
            update_tree(x,z);
        }
        if(opt==4){
            int x=rd();
            printf("%d\n",que_tree(x));
        }
    }
    return 0;
}

by xhQYm @ 2023-11-09 11:24:16

看成了0-1trie。。。


by kisuti @ 2023-11-09 19:13:42

。。。


|