CF1076E Vasya and a Tree
题意
给出v,d,x,将以v节点的d级子树的权值加上x。
做若干操作后,求每个点的权值
题解
首先肯定是离线,把询问离线到每个节点上
那个树状数组维护
然后到那个节点u的时候把深度dep[u]~dep[u]+d的全部加上x,回溯的时候再去掉
然后就好了
// luogu-judger-enable-o2
#include<bits/stdc++.h>
#define N 1000005
#define int long long
#define lowbit(x) (x & -x)
using namespace std;
struct A{
int d, x;
};
vector<A> a[N];
struct edge{
int v, nxt;
}e[N];
int p[N], eid;
void init(){
memset(p, -1, sizeof p);
eid = 0;
}
void insert(int u, int v){
e[eid].v = v;
e[eid].nxt = p[u];
p[u] = eid ++;
}
int tree[N];
void update(int x, int y){
for(; x < N; x += lowbit(x)) tree[x] += y;
}
int query(int x){
int ret = 0;
for(; x; x -= lowbit(x)) ret += tree[x];
return ret;
}
int n, m, ANS[N];
void dfs(int u, int fa, int dep){
for(int i = 0; i < a[u].size(); i ++) update(min(n, dep + a[u][i].d), a[u][i].x);
ANS[u] = query(n) - query(dep - 1);
for(int i = p[u]; i + 1; i = e[i].nxt){
int v = e[i].v;
if(v == fa) continue;
dfs(v, u, dep + 1);
}
for(int i = 0; i < a[u].size(); i ++) update(min(n, dep + a[u][i].d), - a[u][i].x);
}
signed main(){
init();
scanf("%lld", &n);
for(int i = 1; i < n; i ++){
int u, v;
scanf("%lld%lld", &u, &v);
insert(u, v);
insert(v, u);
}
scanf("%lld", &m);
for(int i = 1; i <= m; i ++){
int u, d, x;
scanf("%lld%lld%lld", &u, &d, &x);
a[u].push_back(A{d, x});
}
dfs(1, 0, 1);
for(int i = 1; i <= n; i ++) printf("%lld ", ANS[i]);
return 0;
}