zoukankan      html  css  js  c++  java
  • LUOGU P3178 [HAOI2015]树上操作

    传送门

    解题思路

    树链剖分裸题,线段树维护。

    代码

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #define int long long
    
    using namespace std;
    const int MAXN = 100005;
    
    inline int rd(){
        int x=0,f=1;char ch=getchar();
        while(!isdigit(ch)) {f=ch=='-'?0:1;ch=getchar();}
        while(isdigit(ch))  {x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
        return f?x:-x;
    }
    
    int n,m,a[MAXN],sum[MAXN<<2],lazy[MAXN<<2];
    int w[MAXN],id[MAXN],fa[MAXN],dep[MAXN],son[MAXN],siz[MAXN],top[MAXN];
    int num,head[MAXN],cnt,to[MAXN<<1],nxt[MAXN<<1];
    
    inline void add(int bg,int ed){
        to[++cnt]=ed,nxt[cnt]=head[bg],head[bg]=cnt;
    }
    
    void dfs1(int x,int f,int d){
        dep[x]=d,fa[x]=f,siz[x]=1;
        int maxson=-1;
        for(register int i=head[x];i;i=nxt[i]){
            int u=to[i];if(u==f) continue;
            dfs1(u,x,d+1);
            siz[x]+=siz[u];
            if(siz[u]>maxson) {maxson=siz[u];son[x]=u;}
        }
    }
    
    void dfs2(int x,int topf){
        id[x]=++num,w[num]=a[x],top[x]=topf;
        if(!son[x]) return;
        dfs2(son[x],topf);
        for(register int i=head[x];i;i=nxt[i]){
            int u=to[i];if(u==fa[x] || u==son[x]) continue;
            dfs2(u,u);
        }
    }
    
    //----------------------xds------------------------
    
    inline void pushdown(int x,int ln,int rn){
        sum[x<<1]+=ln*lazy[x],sum[x<<1|1]+=rn*lazy[x];
        lazy[x<<1]+=lazy[x],lazy[x<<1|1]+=lazy[x];
        lazy[x]=0;
    }
    
    void build(int x,int l,int r){
        if(l==r){
            sum[x]=w[l];
            return;
        }
        int mid=l+r>>1;
        build(x<<1,l,mid);
        build(x<<1|1,mid+1,r);
        sum[x]=sum[x<<1]+sum[x<<1|1];
    }
    
    void update(int x,int l,int r,int L,int R,int k){
        if(L<=l && r<=R){
            sum[x]+=(r-l+1)*k;
            lazy[x]+=k;
            return;
        }
        int mid=l+r>>1;
        if(lazy[x]) pushdown(x,mid-l+1,r-mid);
        if(mid>=L) update(x<<1,l,mid,L,R,k);
        if(mid<R)  update(x<<1|1,mid+1,r,L,R,k);
        sum[x]=sum[x<<1]+sum[x<<1|1];  
    }
    
    int query(int x,int l,int r,int L,int R){
        if(L<=l && r<=R) return sum[x];
        int mid=l+r>>1,ret=0;
        if(lazy[x]) pushdown(x,mid-l+1,r-mid);
        if(mid>=L) ret+=query(x<<1,l,mid,L,R);
        if(mid<R)  ret+=query(x<<1|1,mid+1,r,L,R);
        return ret;
    }
    
    int qSon(int x){
        int ret=0;
        while(top[x]!=1){
            ret+=query(1,1,n,id[top[x]],id[x]);
            x=fa[top[x]];
        }
        ret+=query(1,1,n,1,id[x]);
        return ret;
    }
    
    signed main(){
        n=rd(),m=rd();
        for(register int i=1;i<=n;i++) a[i]=rd();
        int op,x,y,z;
        for(register int i=1;i<n;i++){
            x=rd(),y=rd();
            add(x,y),add(y,x);
        }
        dfs1(1,0,1),dfs2(1,1);
    //  for(register int i=1;i<=n;i++) cout<<id[i]<<" ";cout<<endl;
        build(1,1,n);
        while(m--){
            op=rd();
            if(op==1){
                x=rd(),z=rd();
                update(1,1,n,id[x],id[x],z);
            }
            else if(op==2){
                x=rd(),z=rd();
                update(1,1,n,id[x],id[x]+siz[x]-1,z);
            }
            else {
                int x=rd();
                printf("%lld
    ",qSon(x));
            }
        }
        return 0;
    }
  • 相关阅读:
    Docker windows下安装,入门及注意事项,并搭建包含Nodejs的webapp
    360浏览器table中的td为空时td边框不显示的解决方法
    关于发布webservice提示The test form is only available for requests from the local machine
    CRM相关SQl手记
    页面右下角弹出的消息提示框
    MS CRM2011 js常用总结
    MVC razor 使用服务器控件
    常用正则表达式
    CRM 2011 常用对象
    人工智能AI-机器视觉CV-数据挖掘DM-机器学习ML-神经网络-[资料集合贴]
  • 原文地址:https://www.cnblogs.com/sdfzsyq/p/9676846.html
Copyright © 2011-2022 走看看