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

    搞了好几天终于把树剖模板过了
    感觉最难理解的是对两点之间路径上的修改,我就是在这里被卡了好久
    还是看注释吧
    原题链接:https://www.luogu.org/problemnew/show/P3384

    #include<bits/stdc++.h>
    #define mid ((l+r)>>1)
    #define sw(x,y) jzm=x,x=y,y=jzm;
    #define For(i,j,k) for(int i=j;i<=k;++i)
    using namespace std;
    int read(){
        int x=0,l=1; char ch=getchar();
        while(!isdigit(ch)) {if (ch=='-') l=-1; ch=getchar();}
        while(isdigit(ch)) x=x*10+(ch^48),ch=getchar();
        return x*l;
    }
    typedef long long ll;
    const int N=100005;
    struct node{
        ll w,en;
    }a[N*3];
    int jzm,e,b[N],head[N],to[N<<1],nex[N<<1],mp[N],mp2[N];
    void ad(int x,int y){
        to[++e]=y; nex[e]=head[x]; head[x]=e;
    }
    void bt(int x,int l,int r){
        if (l==r) {a[x].w=b[mp2[l]]; return;}
        bt(x<<1,l,mid); bt(x<<1|1,mid+1,r);
        a[x].w=a[x<<1].w+a[x<<1|1].w;
    }
    int xx,yy,n,m,r,p; ll k;
    void pd(int fl,int l,int r){
        a[fl<<1].w+=a[fl].en*(mid-l+1);
        a[fl<<1|1].w+=a[fl].en*(r-mid);
        a[fl<<1].en+=a[fl].en;
        a[fl<<1|1].en+=a[fl].en;
        a[fl].en=0;
    }
    void add(int fl,int l,int r){
        if (l>=xx&&r<=yy){
            a[fl].w+=k*(r-l+1); a[fl].en+=k; return;
        }
        if (a[fl].en) pd(fl,l,r);
        if (mid>=xx) add(fl<<1,l,mid);
        if (mid<yy) add(fl<<1|1,mid+1,r);
        a[fl].w=a[fl<<1].w+a[fl<<1|1].w;
    }
    ll qu(int fl,int l,int r){
        if (l>=xx&&r<=yy) return a[fl].w;
        ll an=0;
        if (a[fl].en) pd(fl,l,r);
        if (mid>=xx) an+=qu(fl<<1,l,mid);
        if (mid<yy) an+=qu(fl<<1|1,mid+1,r);
        return an;
    }
    int cnt,siz[N],son[N],top[N],dep[N],fa[N];
    void dfs1(int x,int de,int f){
        siz[x]=1; dep[x]=de++; fa[x]=f; int ma=0;
        for(int i=head[x];i;i=nex[i])
            if (to[i]!=f){
                dfs1(to[i],de,x);
                if (ma<siz[to[i]]) ma=siz[to[i]],son[x]=to[i];
                siz[x]+=siz[to[i]];
            }
    }
    void dfs2(int x,int tp){
        mp[x]=++cnt; top[x]=tp;
        if (son[x]){
            dfs2(son[x],tp);
            for(int i=head[x];i;i=nex[i])
                if (to[i]!=fa[x]&&to[i]!=son[x]) dfs2(to[i],to[i]);
        }
    }
    int main(){
        int x,y,fl,hk,wal,lca,de,f; ll ans; n=read(),m=read(),r=read(),p=read();
        For(i,1,n) b[i]=read();
        For(i,1,n-1){
            x=read(),y=read();
            ad(x,y); ad(y,x);
        }
        dfs1(r,1,0); dfs2(r,r);
        For(i,1,n) mp2[mp[i]]=i; bt(1,1,n);
        For(i,1,m){
            fl=read(),x=read();
            if (fl==3) xx=mp[x],yy=xx+siz[x]-1,k=read(),add(1,1,n);
            else if (fl==4) xx=mp[x],yy=xx+siz[x]-1,printf("%lld
    ",qu(1,1,n)%p);
            else if (fl==2){
                y=read(); ans=0;
                while(top[x]!=top[y]){//当两个点不在同一条链上 
                    if(dep[top[x]]<dep[top[y]]) sw(x,y);//把x点改为所在链顶端的深度更深的那个点
                    xx=mp[top[x]]; yy=mp[x]; ans+=qu(1,1,n);//ans加上x点到x所在链顶端 这一段区间的点权和
                    x=fa[top[x]];//把x跳到x所在链顶端的那个点的上面一个点
                }//直到两个点处于一条链上
                if(dep[x]>dep[y]) sw(x,y);//把x点变为深度更浅的那个点
                xx=mp[x]; yy=mp[y]; ans+=qu(1,1,n);//这时再加上此时两个点的区间和即可
                printf("%lld
    ",ans%p);
            }
            //接下来同上
            else{
                y=read(); k=read();
                while(top[x]!=top[y]){
                    if(dep[top[x]]<dep[top[y]]) sw(x,y);
                    xx=mp[top[x]]; yy=mp[x]; add(1,1,n);
                    x=fa[top[x]];
                }
                if(dep[x]>dep[y]) sw(x,y);
                xx=mp[x]; yy=mp[y]; add(1,1,n);
            }
        }
        return 0;
    }
    
  • 相关阅读:
    HDU 4611 Balls Rearrangement 数学
    Educational Codeforces Round 11 D. Number of Parallelograms 暴力
    Knockout.Js官网学习(简介)
    Entity Framework 关系约束配置
    Entity Framework Fluent API
    Entity Framework DataAnnotations
    Entity Framework 系统约定配置
    Entity Framework 自动生成CodeFirst代码
    Entity Framework CodeFirst数据迁移
    Entity Framework CodeFirst尝试
  • 原文地址:https://www.cnblogs.com/wjy666/p/7989279.html
Copyright © 2011-2022 走看看