树上操作

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

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

#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\n",qc(1,x));
        }
    }
    return 0;
}

深深地感到自己的弱小。

posted @ 2020-02-29 22:33  syzf2222  阅读(107)  评论(0编辑  收藏  举报