• 树上操作


    这是一个初学树剖很好的练手题。

    我想我只需要放个代码……

    #include<bits/stdc++.h>
    using namespace std;
    #define int long long
    const int maxn=1000000;
    int n,m;
    int beg[maxn],nex[maxn],to[maxn],e;
    inline void add(int x,int y){
        e++;nex[e]=beg[x];
        beg[x]=e;to[e]=y;
    }
    int dep[maxn],f[maxn],son[maxn],size[maxn];
    inline void dfs1(int x,int fa){
        dep[x]=dep[fa]+1;
        f[x]=fa;
        size[x]=1;
        for(int i=beg[x];i;i=nex[i]){
            int t=to[i];
            if(t==fa)continue;
            dfs1(t,x);
            size[x]+=size[t];
            if(size[t]>size[son[x]])son[x]=t;
        }
    }
    int val[maxn],id[maxn],num[maxn],top[maxn],cnt;
    inline void dfs2(int x,int topc){
        id[x]=++cnt;
        num[cnt]=val[x];
        top[x]=topc;
        if(!son[x])return;
        dfs2(son[x],topc);
        for(int i=beg[x];i;i=nex[i]){
            int t=to[i];
            if(t==f[x]||t==son[x])
                continue;
            dfs2(t,t);
        }
    }
    int tree[maxn],lazy[maxn];
    inline void build(int h,int l,int r){
        if(l==r){
            tree[h]=num[l];
            return;
        }
        int mid=(l+r)>>1;
        build(h<<1,l,mid);
        build(h<<1|1,mid+1,r);
        tree[h]=tree[h<<1]+tree[h<<1|1];
    }
    inline void pushup(int h,int l,int r,int z){
        tree[h]+=(r-l+1)*z;
        lazy[h]+=z;
    }
    inline void pushdown(int h,int l,int r){
        if(!lazy[h])return;
        int mid=(l+r)>>1;
        pushup(h<<1,l,mid,lazy[h]);
        pushup(h<<1|1,mid+1,r,lazy[h]);
        lazy[h]=0;
    }
    inline void update(int h,int l,int r,int x,int y,int z){
        if(l>y||r<x)return;
        if(l>=x&&r<=y){
            pushup(h,l,r,z);
            return;
        }
        pushdown(h,l,r);
        int mid=(l+r)>>1;
        update(h<<1,l,mid,x,y,z);
        update(h<<1|1,mid+1,r,x,y,z);
        tree[h]=tree[h<<1]+tree[h<<1|1];
    }
    inline int query(int h,int l,int r,int x,int y){
        if(l>y||r<x)return 0;
        if(l>=x&&r<=y)return tree[h];
        pushdown(h,l,r);
        int mid=(l+r)>>1;
        return query(h<<1,l,mid,x,y)+query(h<<1|1,mid+1,r,x,y);
    }
    inline int qc(int x,int y){
        int ans=0;
        while(top[x]!=top[y]){
            if(dep[top[x]]<dep[top[y]])swap(x,y);
            ans+=query(1,1,n,id[top[x]],id[x]);
            x=f[top[x]];
        }
        if(dep[x]>dep[y])swap(x,y);
        ans+=query(1,1,n,id[x],id[y]);
        return ans;
    }
    signed main(){
        cin>>n>>m;
        for(int i=1;i<=n;i++)
            scanf("%lld",&val[i]);
        for(int i=1;i<n;i++){
            int x,y;
            scanf("%lld%lld",&x,&y);
            add(x,y);
            add(y,x);
        }
        dfs1(1,0);
        dfs2(1,1);
        build(1,1,n);
        for(int i=1;i<=m;i++){
            int opt;
            scanf("%lld",&opt);
            if(opt==1){
                int x,a;
                scanf("%lld%lld",&x,&a);
                update(1,1,n,id[x],id[x],a);
            }else if(opt==2){
                int x,a;
                scanf("%lld%lld",&x,&a);
                update(1,1,n,id[x],id[x]+size[x]-1,a);
            }else{
                int x;
                scanf("%lld",&x);
                printf("%lld
    ",qc(1,x));
            }
        }
        return 0;
    }

    深深地感到自己的弱小。

  • 相关阅读:
    04-老马jQuery教程-DOM节点操作及位置和大小
    03-老马jQuery教程-DOM操作
    02-老马jQuery教程-jQuery事件处理
    01-老马jQuery教程-jQuery入口函数及选择器
    08Vue.js快速入门-Vue综合实战项目
    09Vue.js快速入门-Vue入门之Vuex实战
    07Vue.js快速入门-Vue路由详解
    06Vue.js快速入门-Vue组件化开发
    整套高质量前端基础到高级视频教程免费发布
    05-Vue入门系列之Vue实例详解与生命周期
  • 原文地址:https://www.cnblogs.com/syzf2222/p/12386687.html
Copyright © 2020-2023  润新知