zoukankan      html  css  js  c++  java
  • 树上操作

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

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

    #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;
    }

    深深地感到自己的弱小。

  • 相关阅读:
    Linux 命令汇总总结相关
    数据结构---python---表
    python-----Queue模块
    再看python多线程------threading模块
    <转> Struct 和 Union区别 以及 对内存对齐方式的说明
    python装饰器
    HTTP权威指南----缓存
    HTTP权威指南----连接管理
    以python理解Linux的IO多路复用,select、poll、epoll
    <转载> pycharm快捷键及一些常用设置
  • 原文地址:https://www.cnblogs.com/syzf2222/p/12386687.html
Copyright © 2011-2022 走看看