zoukankan      html  css  js  c++  java
  • bzoj 4034: [HAOI2015]树上操作——树链剖分

    Description

    有一棵点数为 N 的树,以点 1 为根,且树点有边权。然后有 M 个
    操作,分为三种:
    操作 1 :把某个节点 x 的点权增加 a 。
    操作 2 :把某个节点 x 为根的子树中所有点的点权都增加 a 。
    操作 3 :询问某个节点 x 到根的路径中所有点的点权和。

    Input

    第一行包含两个整数 N, M 。表示点数和操作数。接下来一行 N 个整数,表示树中节点的初始权值。接下来 N-1 
    行每行三个正整数 fr, to , 表示该树中存在一条边 (fr, to) 。再接下来 M 行,每行分别表示一次操作。其中
    第一个数表示该操作的种类( 1-3 ) ,之后接这个操作的参数( x 或者 x a ) 。
     

    Output

    对于每个询问操作,输出该询问的答案。答案之间用换行隔开。

     

    Sample Input

    5 5
    1 2 3 4 5
    1 2
    1 4
    2 3
    2 5
    3 3
    1 2 1
    3 5
    2 1 2
    3 3

    Sample Output

    6
    9
    13

    HINT

     对于 100% 的数据, N,M<=100000 ,且所有输入数据的绝对值都不会超过 10^6 。

    —————————————————————————————

    这道题其实也是裸题QAQ 子树求和就是求个子树内id最大的点 从根到这个点的编号刚好包含了整个子树

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #define LL long long
    const int M=150007;
    int read(){
        int ans=0,f=1,c=getchar();
        while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();}
        while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();}
        return ans*f;
    }
    int max(int x,int y){return x>y?x:y;}
    int n,m;
    int first[M],cnt=1;
    struct node{int to,next;}e[2*M];
    void ins(int a,int b){e[++cnt]=(node){b,first[a]}; first[a]=cnt;}
    void insert(int a,int b){ins(a,b); ins(b,a);}
    int top[M],sz[M],son[M],mx[M],fa[M],id[M],idp=1;
    void f1(int x){
        sz[x]=1;
        for(int i=first[x];i;i=e[i].next){
            int now=e[i].to;
            if(now==fa[x]) continue;
            fa[now]=x; f1(now);
            sz[x]+=sz[now]; 
            if(sz[now]>sz[son[x]]) son[x]=now;
        }
    }
    void f2(int x,int tp){
        top[x]=tp; mx[x]=id[x]=idp++;
        if(son[x]) f2(son[x],tp),mx[x]=max(mx[x],mx[son[x]]);
        for(int i=first[x];i;i=e[i].next){
            int now=e[i].to;
            if(now!=fa[x]&&now!=son[x]) f2(now,now),mx[x]=max(mx[x],mx[now]);
        }
    }
    struct pos{int l,r; LL sum,tag;}tr[4*M];
    void build(int x,int l,int r){
        tr[x].l=l; tr[x].r=r;
        if(l==r) return ;
        int mid=(l+r)>>1;
        build(x<<1,l,mid);
        build(x<<1^1,mid+1,r);
    }
    void up(int x){tr[x].sum=tr[x<<1].sum+tr[x<<1^1].sum;}
    void down(int x){
        if(tr[x].tag){
            int ls=x<<1,rs=x<<1^1;
            LL v=tr[x].tag;
            tr[x].tag=0; tr[ls].tag+=v; tr[rs].tag+=v;
            tr[ls].sum+=1LL*(tr[ls].r-tr[ls].l+1)*v;
            tr[rs].sum+=1LL*(tr[rs].r-tr[rs].l+1)*v;
        }
    }
    void modify(int x,int L,int R,LL s){
        if(L<=tr[x].l&&tr[x].r<=R){tr[x].tag+=s; tr[x].sum+=(tr[x].r-tr[x].l+1)*s; return ;}
        down(x);
        int mid=(tr[x].l+tr[x].r)>>1;
        if(L<=mid) modify(x<<1,L,R,s);
        if(R>mid) modify(x<<1^1,L,R,s);
        up(x);
    }
    LL v[M];
    LL push_sum(int x,int L,int R){
        if(L<=tr[x].l&&tr[x].r<=R) return tr[x].sum;
        down(x);
        int mid=(tr[x].l+tr[x].r)>>1;
        LL ans=0;
        if(L<=mid) ans+=push_sum(x<<1,L,R);
        if(R>mid)  ans+=push_sum(x<<1^1,L,R);
        return ans;
    }
    LL qsum(int x){
        LL sum=0;
        while(top[x]!=top[1]){
            sum+=push_sum(1,id[top[x]],id[x]);
            x=fa[top[x]];
        }
        sum+=push_sum(1,id[1],id[x]);
        return sum;
    }
    int main(){
        int k,x,y;
        n=read(); m=read();
        for(int i=1;i<=n;i++) v[i]=read();
        for(int i=1;i<n;i++) x=read(),y=read(),insert(x,y);
        build(1,1,n); f1(1); f2(1,1);
        for(int i=1;i<=n;i++) modify(1,id[i],id[i],v[i]);
        for(int i=1;i<=m;i++){
            k=read();
            if(k==1) x=read(),y=read(),modify(1,id[x],id[x],y);
            else if(k==2) x=read(),y=read(),modify(1,id[x],mx[x],y);
            else x=read(),printf("%lld
    ",qsum(x));
        }
        return 0;
    }
    View Code
  • 相关阅读:
    MySQL监控全部执行过的sql语句
    Linux之网络编程:时间服务器
    人生哲理 |南怀瑾最经典的50句话
    TCP/IP协议(一)网络基础知识 网络七层协议
    Linux下进程通信之管道
    一个完整的项目管理流程
    Linux编程之select
    (笔记)电路设计(十四)之放大器的应用
    ds18b20采集温度并上报服务器
    java中基于swing库自定义分页组件
  • 原文地址:https://www.cnblogs.com/lyzuikeai/p/7623268.html
Copyright © 2011-2022 走看看