Vasya and a Tree [contest/1076 E]

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/z591826160/article/details/84027280

Vasya and a Tree [contest/1076 E]

题面

在这里插入图片描述

思路

看到修改一个子树内容,第一反应是打标记,但由于只修改深度范围内的节点,容易想到用类似差分的思想去做。说到差分那首选就是树状数组了,维护每个节点的修改情况,进入节点时,将拆分内容加入线段树,出该节点时恢复差分情况即可

代码

int n,m;
vector<int>G[maxn];
vector<pair<int,int> >update[maxn];
int dep[maxn];
ll tree[maxn],ans[maxn];
void add(int u,ll c){
    while(u<=n){
        tree[u]+=c;
        u+=lowbit(u);
    }
}
ll query(int u){
    ll ans=0;
    while(u){
        ans+=tree[u];
        u-=lowbit(u);
    }
    return ans;
}
void dfs(int u,int f,int d){
    dep[u]=d;
    rep(i,0,update[u].size()){
        add(dep[u],update[u][i].second);
        add(dep[u]+update[u][i].first+1,-update[u][i].second);
    }
    ans[u]=query(dep[u]);
    rep(i,0,G[u].size()){
        int v=G[u][i];
        if(v==f)continue;
        dfs(v,u,d+1);
    }
    rep(i,0,update[u].size()){
        add(dep[u],-update[u][i].second);
        add(dep[u]+update[u][i].first+1,update[u][i].second);
    }
}
int main(){
    rd(n);
    rep(i,1,n){
        int a,b;
        rd(a,b);
        G[a].pb(b);G[b].pb(a);
    }
    rd(m);
    rep(i,0,m){
        int a,b,c;
        rd(a,b,c);
        update[a].pb(mp(b,c));
    }
    dfs(1,-1,1);
    rep(i,1,n+1)
        printf("%lld ",ans[i]);
}

猜你喜欢

转载自blog.csdn.net/z591826160/article/details/84027280
今日推荐