Vasya and a Tree
Problem Description
Vasya has a tree consisting of n vertices with root in vertex 1. At first all vertices has 0 written on it.
Let d ( i , j ) d(i,j) d(i,j) be the distance between vertices i and j, i.e. number of edges in the shortest path from i to j. Also, let’s denote k-subtree of vertex x — set of vertices y such that next two conditions are met:
- x is the ancestor of y (each vertex is the ancestor of itself);
- d ( x , y ) ≤ k d(x,y)≤k d(x,y)≤k.
Vasya needs you to process m queries. The i-th query is a triple vi, di and xi. For each query Vasya adds value xi to each vertex from di-subtree of vi.
Report to Vasya all values, written on vertices of the tree after processing all queries.
Input
The first line contains single integer n (1≤n≤3⋅105) — number of vertices in the tree.
Each of next n−1 lines contains two integers x and y (1≤x,y≤n) — edge between vertices x and y. It is guarantied that given graph is a tree.
Next line contains single integer m (1≤m≤3⋅105) — number of queries.
Each of next m lines contains three integers vi, di, xi (1≤vi≤n, 0≤di≤109, 1≤xi≤109) — description of the i-th query.
Output
Print n integers. The i-th integers is the value, written in the i-th vertex after processing all queries.
Sample Input
5
1 2
1 3
2 4
2 5
3
1 1 1
2 0 10
4 10 100
Sample Output
1 11 1 100 0
题意
一棵以1号为根,共有n个节点的树,每个节点初始值为0。每次操作可以将以u为根的子树中与其距离不超过k的所有节点都加上x,求所有操作完成后每个节点的值。
题解:
DFS,对于每个节点,假设当前节点u,深度为height。设add[i] 表示深度为i开始需要加的x的和。那个对于从u开始的每操作,DFS向下时,可以令 a d d [ h e i g e h t ] + = x add[heigeht] += x add[heigeht]+=x , a d d [ h e i g h t + k + 1 ] − = x add[height+k+1] -= x add[height+k+1]−=x,然后递归向下时,设累加变量sum加上add[u]。同时在u递归结束时,需要将add对应的部分进行加减,以消去u的影响。
#include<cstdio>
#include<iostream>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#include<ctype.h>
#include<cstring>
#include<vector>
#include<queue>
#include<map>
#include<iterator>
#define dbg(x) cout<<#x<<" = "<<x<<endl;
#define INF 0x3f3f3f3f
#define eps 1e-8
using namespace std;
typedef long long LL;
typedef pair<int, int> P;
const int maxn = 300100;
const int mod = 1000000007;
LL add[maxn], ans[maxn];
vector<int> g[maxn];
vector<P> que[maxn];
void dfs(int u, int hei, int fa, LL sum);
int main()
{
int n, m, f, t, i;
scanf("%d", &n);
for(i=1;i<n;i++){
scanf("%d %d", &f, &t);
g[f].push_back(t);
g[t].push_back(f);
}
scanf("%d", &m);
for(i=0;i<m;i++)
{
int w;
scanf("%d %d %d", &f, &t, &w);
que[f].push_back(P(t, w));
}
dfs(1, 0, 0, 0);
for(i=1;i<=n;i++)
{
if(i>1)printf(" ");
printf("%I64d", ans[i]);
}
printf("\n");
return 0;
}
void dfs(int u, int hei, int fa, LL sum)
{
int i;
for(i=0;i<que[u].size();i++)
{
int h = min(hei + que[u][i].first+1, maxn-10);
add[hei] += que[u][i].second;
add[h] -= que[u][i].second;
}
sum += add[hei];
ans[u] = sum;
for(i=0;i<g[u].size();i++)
if(g[u][i] != fa)
dfs(g[u][i], hei+1, u, sum);
for(i=0;i<que[u].size();i++)
{
int h = min(hei + que[u][i].first+1, maxn-10);
add[hei] -= que[u][i].second;
add[h] += que[u][i].second;
}
}