zoukankan      html  css  js  c++  java
  • 树链剖分

    树链剖分

    #include<iostream>
    #include<cstdio>
    using namespace std;
    #define ci const int&
    #define ri register int
    #define rc register char
    #define ls rt<<1
    #define rs rt<<1|1
    #define N 100100
    struct edge{
        int nxt,to;
    } E[N<<1];
    struct node{
        int w,l,r,siz,lz;
    } T[N<<2];
    int n,m,r,p,x,y,z,op;
    int w[N],Tw[N];
    int cnt,rt;
    int head[N],fa[N],son[N],top[N],dep[N],siz[N],id[N];
    inline int read(){
        ri res=0,bf=1;
        rc c=getchar();
        for(;c<'0' || c>'9';c=getchar())
            if(c=='-')
                bf=-1;
        for(;c>='0' && c<='9';c=getchar())
            res=(res<<3)+(res<<1)+(c^'0');
        return bf*res;
    }
    void write(ci x){
        if(x>9)
            write(x/10);
        putchar(x%10^'0');
    }
    inline void add(ci u,ci v){
        E[++cnt].nxt=head[u];
        E[cnt].to=v;
        head[u]=cnt;
    }
    inline void pushup(ci rt){
        (T[rt].w=T[ls].w+T[rs].w)%=p;
    }
    inline void pushdown(ci rt){
        (T[ls].lz+=T[rt].lz)%=p;
        (T[rs].lz+=T[rt].lz)%=p;
        (T[ls].w+=T[rt].lz*T[ls].siz)%=p;
        (T[rs].w+=T[rt].lz*T[rs].siz)%=p;
        T[rt].lz=0;
    }
    void build(ci rt,ci l,ci r){
        T[rt].l=l,T[rt].r=r;
        T[rt].siz=r-l+1;
        if(l==r){
            T[rt].w=Tw[l];
            return;
        }
        ri mid=(l+r)>>1;
        build(ls,l,mid);
        build(rs,mid+1,r);
        pushup(rt);
    }
    void update(ci rt,ci l,ci r,ci k){
        if(T[rt].l>=l && T[rt].r<=r){
            (T[rt].w+=T[rt].siz*k)%=p;
            (T[rt].lz+=k)%=p;
            return;
        }
        if(T[rt].lz)
            pushdown(rt);
        ri mid=(T[rt].l+T[rt].r)>>1;
        if(l<=mid)
            update(ls,l,r,k);
        if(r>mid)
            update(rs,l,r,k);
        pushup(rt);
    }
    int query(ci rt,ci l,ci r){
        if(T[rt].l>=l && T[rt].r<=r)
            return T[rt].w;
        if(T[rt].lz)
            pushdown(rt);
        ri res=0;
        ri mid=(T[rt].l+T[rt].r)>>1;
        if(l<=mid)
            res+=query(ls,l,r);
        if(r>mid)
            res+=query(rs,l,r);
        return res%p;
    }
    void dfs1(ci u,ci f,ci d){
        siz[u]=1;
        dep[u]=d;
        fa[u]=f;
        for(ri i=head[u];i;i=E[i].nxt){
            ri v=E[i].to;
            if(v==fa[u])
                continue;
            dfs1(v,u,d+1);
            siz[u]+=siz[v];
            if(siz[v]>siz[son[u]])
                son[u]=v;
        }
    }
    void dfs2(ci u,ci t){
        top[u]=t;
        id[u]=++cnt;
        Tw[cnt]=w[u];
        if(!son[u])
            return;
        dfs2(son[u],t);
        for(ri i=head[u];i;i=E[i].nxt){
            ri v=E[i].to;
            if(v==son[u] || v==fa[u])
                continue;
            dfs2(v,v);
        }
    }
    inline void Tadd(int x,int y,int k){
        for(;top[x]!=top[y];){
            if(dep[top[x]]<dep[top[y]])
                swap(x,y);
            update(1,id[top[x]],id[x],k);
            x=fa[top[x]];
        }
        if(dep[x]>dep[y])
            swap(x,y);
        update(1,id[x],id[y],k);
    }
    inline int Tsum(int x,int y){
        ri res=0;
        for(;top[x]!=top[y];){
            if(dep[top[x]]<dep[top[y]])
                swap(x,y);
            res+=query(1,id[top[x]],id[x])%p;
            x=fa[top[x]];
        }
        if(dep[x]>dep[y])
            swap(x,y);
        res+=query(1,id[x],id[y]);
        return res%p;
    }
    int main(){
        n=read(),m=read(),r=read(),p=read();
        for(ri i=1;i<=n;i++)
            w[i]=read();
        for(ri i=1;i<n;i++){
            x=read(),y=read();
            add(x,y);
            add(y,x);
        }
        cnt=0;
        dfs1(r,0,1);
        dfs2(r,r);
        build(1,1,n);
        for(ri i=1;i<=m;i++){
            op=read();
            if(op==1){
                x=read(),y=read(),z=read();
                Tadd(x,y,z);
            }
            else if(op==2){
                x=read(),y=read();
                write(Tsum(x,y));
                puts("");
            }
            else if(op==3){
                x=read(),z=read();
                update(1,id[x],id[x]+siz[x]-1,z);
            }
            else if(op==4){
                x=read();
                write(query(1,id[x],id[x]+siz[x]-1));
                puts("");
            }
        }
        return 0;
    }
    
  • 相关阅读:
    sparql学习sparql示例、dbpedia在线验证
    中国绿卡
    逾期率的水有多深,你知道吗?
    ICO和区块链区别
    What are the benefits to using anonymous functions instead of named functions for callbacks and parameters in JavaScript event code?
    Link static data in sql source control
    sql data compare
    viewbag
    多态的实际使用
    win10 sedlauncher.exe占用cpu处理
  • 原文地址:https://www.cnblogs.com/pelom/p/10279794.html
Copyright © 2011-2022 走看看