zoukankan      html  css  js  c++  java
  • [BZOJ]4034: [HAOI2015]树上操作

    [HAOI2015]树上操作

    传送门

    题目大意:三个操作 1:a,b,c b节点权值+c 2:a,b,c 以b为根的子树节点权值全部+c 3:a,b 查询b到根路径的权值和。

    题解:树链剖分

    操作1 ,2是区间修改,3是区间和。

    看题解都提示开long long 了,我也开了,可是整形相乘赋值给Long long时爆了。

    简直要哭晕了。

    代码:

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #define maxn 500005
    #define LL long long
    using namespace std;
    
    int sumedge,cnt,n,m;
    int head[maxn],size[maxn],dad[maxn],deep[maxn],top[maxn];
    int tpos[maxn],re[maxn],w[maxn];
    
    struct Tree{
        int l,r;LL sum,s;
    }tr[maxn<<2];
    
    struct Edge{
        int x,y,nxt;
        Edge(int x=0,int y=0,int nxt=0):
            x(x),y(y),nxt(nxt){}
    }edge[maxn<<1];
    
    
    void read(int &x){
        char ch=getchar();x=0;int f=1;
        for(;!isdigit(ch);ch=getchar())if(ch=='-')f=-1;
        for(;isdigit(ch);ch=getchar())x=x*10+ch-'0';
        x=x*f;
    }
    
    void add(int x,int y){
        edge[++sumedge]=Edge(x,y,head[x]);
        head[x]=sumedge;
    }
    
    void dfs(int x){
        size[x]=1;deep[x]=deep[dad[x]]+1;
        for(int i=head[x];i;i=edge[i].nxt){
            int v=edge[i].y;
            if(v==dad[x])continue;
            dad[v]=x;dfs(v);
            size[x]+=size[v];
        }
    }
    
    void dfs_(int x){
        int s=0;tpos[x]=++cnt;re[cnt]=x;
        if(!top[x])top[x]=x;
        for(int i=head[x];i;i=edge[i].nxt){
            int v=edge[i].y;
            if(v!=dad[x]&&size[v]>size[s])s=v;
        }
        if(s){
            top[s]=top[x];
            dfs_(s);
        }
        for(int i=head[x];i;i=edge[i].nxt){
            int v=edge[i].y;
            if(v!=dad[x]&&v!=s)dfs_(v);
        }
    }
    
    void pushup(int rt){
        tr[rt].sum=tr[rt<<1].sum+tr[rt<<1|1].sum;
        return;
    }
    
    void pushdown(int rt){
        if(!tr[rt].s)return;
        tr[rt<<1].s+=tr[rt].s;tr[rt<<1|1].s+=tr[rt].s;
        tr[rt<<1].sum+=(LL)(tr[rt<<1].r-tr[rt<<1].l+1)*tr[rt].s;
        tr[rt<<1|1].sum+=(LL)(tr[rt<<1|1].r-tr[rt<<1|1].l+1)*tr[rt].s;
        tr[rt].s=0;return;
    }
    
    void build(int rt,int l,int r){
        tr[rt].l=l;tr[rt].r=r;
        if(l==r){
            tr[rt].sum=w[re[l]];
            return;
        }
        int mid=(l+r)>>1;
        build(rt<<1,l,mid);build(rt<<1|1,mid+1,r);
        pushup(rt);
    }
    
    void change(int rt,int l,int r,int ql,int qr,int p){
        if(l>=ql&&r<=qr){
            tr[rt].sum+=(LL)(r-l+1)*p;
            tr[rt].s+=p;
            return;
        }
        pushdown(rt);
        int mid=(l+r)>>1;
        if(ql<=mid)change(rt<<1,l,mid,ql,qr,p);
        if(qr>mid)change(rt<<1|1,mid+1,r,ql,qr,p);
        pushup(rt);
    }
    
    LL query_sum(int rt,int l,int r,int ql,int qr){
        if(l>=ql&&r<=qr){
            return tr[rt].sum;
        }
        pushdown(rt);
        int mid=(l+r)>>1;LL ans=0;
        if(ql<=mid)ans+=query_sum(rt<<1,l,mid,ql,qr);
        if(qr>mid)ans+=query_sum(rt<<1|1,mid+1,r,ql,qr);
        return ans;
    }
    
    LL query(int x){
        LL ret=0;
        for(;top[x]!=1;){
            ret+=query_sum(1,1,n,tpos[top[x]],tpos[x]);
            x=dad[top[x]];
        }
        ret+=query_sum(1,1,n,1,tpos[x]);
        return ret;
    }
    
    int main(){
        read(n);read(m);
        for(int i=1;i<=n;i++)read(w[i]);
        for(int i=1;i<n;i++){
            int x,y;
            read(x);read(y);
            add(x,y);add(y,x);
        }
        dfs(1);dfs_(1);build(1,1,n);
        for(int i=1;i<=m;i++){
            int od,x,a;
            read(od);read(x);
            if(od==1){
                read(a);
                change(1,1,n,tpos[x],tpos[x],a);
            }else if(od==2){
                read(a);
                change(1,1,n,tpos[x],tpos[x]+size[x]-1,a);
            }else if(od==3){
                printf("%lld
    ",query(x));
            }
        }
        return 0;
    }
    AC
  • 相关阅读:
    转C#线程调用带参数的方法 ~
    转在本地计算机无法启动oracledbconsole服务。错误1053:服务没有及时响应启动或控制请求
    转对Oracle10修改机器名后服务无法启动的解决
    转Spring.net web.config配置文件(经过整理和修改)
    转C#修饰符
    IP地址比较方法
    [转贴]关于XmlDocument 和 XPathDocument
    javascript下调用正则表达式的方法
    bug小结
    SQL Cache Dependency
  • 原文地址:https://www.cnblogs.com/zzyh/p/7700660.html
Copyright © 2011-2022 走看看