zoukankan      html  css  js  c++  java
  • BZOJ 2836 树链剖分+线段树

    思路:
    链剖+线段树裸题

    重链的标号就是DFS序

    所以查子树的时候每回就 query(change[x],change[x]+size[x]-1)
    就好了

    剩下的应该都会吧。。

    //By SiriusRen
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    #define int long long
    #define N 100050
    char op[19];
    int n,m,xx,yy,ww,first[N],next[N],v[N],tot,tree[N*16],mark[N*16];
    int fa[N],rec[N],cnt,deep[N],size[N],son[N],top[N],p[N];
    void add(int x,int y){v[tot]=y,next[tot]=first[x],first[x]=tot++;}
    void dfs(int x){
        size[x]=1,son[x]=-1;
        for(int i=first[x];~i;i=next[i]){
            deep[v[i]]=deep[x]+1;
            dfs(v[i]);
            size[x]+=size[v[i]];
            if(son[x]==-1||size[v[i]]>size[son[x]])son[x]=v[i];
        }
    }
    void dfs2(int x,int tp){
        top[x]=tp,rec[x]=++cnt;
        if(~son[x])dfs2(son[x],tp);
        for(int i=first[x];~i;i=next[i]){
            if(v[i]!=son[x])dfs2(v[i],v[i]);
        }
    }
    void push_down(int pos,int cover){
        int lson=pos<<1,rson=pos<<1|1;
        mark[lson]+=mark[pos],mark[rson]+=mark[pos];
        tree[lson]+=(cover-cover/2)*mark[pos];
        tree[rson]+=cover/2*mark[pos];
        mark[pos]=0;
    }
    void insert(int l,int r,int pos,int L,int R,int wei){
        if(l>=L&&r<=R){tree[pos]+=wei*(r-l+1),mark[pos]+=wei;return;}
        if(mark[pos])push_down(pos,r-l+1);
        int mid=(l+r)>>1,lson=pos<<1,rson=pos<<1|1;
        if(mid<L)insert(mid+1,r,rson,L,R,wei);
        else if(mid>=R)insert(l,mid,lson,L,R,wei);
        else insert(l,mid,lson,L,R,wei),insert(mid+1,r,rson,L,R,wei);
        tree[pos]=tree[lson]+tree[rson];
    }
    void Add(int x,int y){
        int fx=top[x],fy=top[y];
        while(fx!=fy){
            if(deep[fx]<deep[fy])swap(x,y),swap(fx,fy);
            insert(1,n,1,rec[fx],rec[x],ww);
            x=fa[fx],fx=top[x];
        }
        if(deep[x]>deep[y])swap(x,y);
        insert(1,n,1,rec[x],rec[y],ww);
    }
    int query(int l,int r,int pos,int L,int R){
        if(l>=L&&r<=R)return tree[pos];
        if(mark[pos])push_down(pos,r-l+1);
        int mid=(l+r)>>1,lson=pos<<1,rson=pos<<1|1;
        if(mid<L)return query(mid+1,r,rson,L,R);
        else if(mid>=R)return query(l,mid,lson,L,R);
        else return query(l,mid,lson,L,R)+query(mid+1,r,rson,L,R);
    }
    signed main(){
        memset(first,-1,sizeof(first));
        scanf("%lld",&n);
        for(int i=1;i<n;i++){
            scanf("%lld%lld",&xx,&yy);
            fa[yy]=xx,add(xx,yy);
        }
        dfs(0),dfs2(0,0);
        scanf("%lld",&m);
        for(int i=1;i<=m;i++){
            scanf("%s",op);
            if(op[0]=='A')scanf("%lld%lld%lld",&xx,&yy,&ww),Add(xx,yy);
            else scanf("%lld",&xx),printf("%lld
    ",query(1,n,1,rec[xx],rec[xx]+size[xx]-1));
        }
    }

    这里写图片描述

  • 相关阅读:
    【bzoj1704】[Usaco2007 Mar]Face The Right Way 自动转身机 贪心
    【poj2104】K-th Number 主席树
    【bzoj3772】精神污染 STL+LCA+主席树
    【bzoj3932】[CQOI2015]任务查询系统 离散化+主席树
    【bzoj3545/bzoj3551】[ONTAK2010]Peaks/加强版 Kruskal+树上倍增+Dfs序+主席树
    【bzoj3524】[Poi2014]Couriers 主席树
    【bzoj2223】[Coci 2009]PATULJCI 主席树
    【bzoj2588】Spoj 10628. Count on a tree 离散化+主席树
    【bzoj1901】Zju2112 Dynamic Rankings 离散化+主席树+树状数组
    【bzoj1552】[Cerc2007]robotic sort Splay
  • 原文地址:https://www.cnblogs.com/SiriusRen/p/6532163.html
Copyright © 2011-2022 走看看