原题地址:https://codeforces.com/contest/1076/problem/E
题意:给出一棵树,有 m m m次操作,每次操作有一个 v , d , x , v,d,x, v,d,x,表示将以 v v v为根节点,距离 v v v的长度小于等于 d d d的所有节点权值加上 x x x,最后求所有节点的权值。
思路:如果是对节点v的子树进行修改,那么问题可以用dfs序转化为序列上的问题,但是这题是对距离为d的进行修改,那么就需要用别的方法。
可以发现修改是区间上的修改,又由于问题是在树上的问题,可以考虑树上差分。我们可以知道,对于一次操作 v , d , x v,d,x v,d,x而言,如果节点v的深度是dep,那么v影响到的节点的深度必然是 [ d e p , d e p + d ] [dep,dep+d] [dep,dep+d],那么我们就可以对深度进行差分,由于 d f s dfs dfs只会往当前节点的子节点进行递归,所以不需要考虑相同深度当不属于v的子树中的点。
注意操作完之后还原现场即可。
#include
#define eps 1e-8
#define INF 0x3f3f3f3f
#define PI acos(-1)
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
#define CLR(x, y) memset((x),y,sizeof(x))
#define fuck(x) cerr << #x << "=" << x << endl;
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int seed = 131;
const int maxn = 3e5 + 5;
const int mod = 1e9 + 7;
/*
给你一棵n个点的树,以1为根。一开始n个点的权值为0,每个边的边长为1.
给你m个操作,每次给v,d,x。
把所有祖先是v的,且距离v不超过d的点的权值都加上x。
*/
int n, m, a[maxn];
const int N = 3e5 + 5;
ll bit[N];
int lowbit(int x) {
return x & -x;
}
void add(int i, ll x) {
while (i < N) {
bit[i] += x;
i += lowbit(i);
}
}
ll query(int i) {
ll sum = 0;
while (i) {
sum += bit[i];
i -= lowbit(i);
}
return sum;
}
struct node {
int v, nxt;
} e[2 * maxn];
int tot, head[maxn];
void add_edge(int u, int v) {
e[tot].v = v;
e[tot].nxt = head[u];
head[u] = tot++;
}
struct nee {
int d, x;
};
vector<nee> vec[maxn];
ll ans[maxn];
void dfs(int u, int fa, int dep) {
int sz = vec[u].size();
for (int i = 0; i < sz; i++) {
int d = vec[u][i].d;
int x = vec[u][i].x;
add(dep, x);
add(dep + d + 1, -x);
}
ans[u] = query(dep);
for (int i = head[u]; ~i; i = e[i].nxt) {
int v = e[i].v;
if (v == fa)continue;
dfs(v, u, dep + 1);
}
for (int i = 0; i < sz; i++) {
int d = vec[u][i].d;
int x = vec[u][i].x;
add(dep, -x);
add(dep + d + 1, x);
}
}
int main() {
#ifndef ONLINE_JUDGE
freopen("in.txt", "r", stdin);
#endif
CLR(head, -1);
scanf("%d", &n);
for (int i = 1; i < n; i++) {
int u, v;
scanf("%d%d", &u, &v);
add_edge(u, v);
add_edge(v,u);
}
scanf("%d", &m);
for (int i = 1; i <= m; i++) {
int v, d, x;
scanf("%d%d%d", &v, &d, &x);
vec[v].push_back(nee{d, x});
}
dfs(1, 1, 1);
for (int i = 1; i <= n; i++) printf("%lld ", ans[i]);
return 0;
}