Codeforces-1076E:Vasya and a Tree(树状数组)

版权声明:http://blog.csdn.net/Mitsuha_。 https://blog.csdn.net/Mitsuha_/article/details/84027193

E. Vasya and a Tree
time limit per test 2 seconds
memory limit per test 256 megabytes
inputstandard input
outputstandard output

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) 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 .

Vasya needs you to process m queries. The i-th query is a triple v i , d i v_i, d_i and x i x_i . For each query Vasya adds value x i x_i to each vertex from di-subtree of v i v_i .

Report to Vasya all values, written on vertices of the tree after processing all quieries.

Input
The first line contains single integer n ( 1 n 3 1 0 5 ) n (1≤n≤3⋅10^5) — number of vertices in the tree.

Each of next n−1 lines contains two integers x and y ( 1 x , y n ) (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 1 0 5 ) m (1≤m≤3⋅10^5) — number of queries.

Each of next m lines contains three integers v i , d i , x i ( 1 v i n , 0 d i 1 0 9 , 1 x i 1 0 9 ) vi, di, xi (1≤v_i≤n, 0≤d_i≤10^9, 1≤x_i≤10^9) — 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.

Examples
input
5
1 2
1 3
2 4
2 5
3
1 1 1
2 0 10
4 10 100
output
1 11 1 100 0
input
5
2 3
2 1
5 4
3 4
5
2 0 4
3 10 1
1 2 3
2 3 10
1 1 7
output
10 24 14 11 11
Note
In the first exapmle initial values in vertices are 0,0,0,0,0. After the first query values will be equal to 1,1,1,0,0. After the second query values will be equal to 1,11,1,0,0. After the third query values will be equal to 1,11,1,100,0.

思路:先将所有操作存下来。然后以深度为节点建立树状数组。从根节点1开始进行DFS。

当遍历到一个节点时,把当前节点的操作影响利用差分更新到树状数组里,然后查询树状数组并更新当前节点答案。

如果把当前节点的所有子节点都遍历完后,再更新树状数组消除当前节点的操作,这样的话再遍历其它节点时,不会产生影响。

#include<bits/stdc++.h>
using namespace std;
const int MAX=1e6+10;
const int MOD=1e9+7;
typedef long long ll;
vector<int>e[MAX];
vector<pair<int,int> >v[MAX];
ll A[MAX];
int n;
void add(int x,int y){while(x<=n){A[x]+=y;x+=x&(-x);}}
ll ask(int x){ll tot=0;while(x){tot+=A[x];x-=x&(-x);}return tot;}
ll ans[MAX];
void dfs(int k,int fa,int d)
{
    for(int i=0;i<v[k].size();i++)
    {
        add(d,v[k][i].second);
        if(d+v[k][i].first+1<=n)add(d+v[k][i].first+1,-v[k][i].second);
    }
    ans[k]=ask(d);
    for(int i=0;i<e[k].size();i++)
    {
        if(e[k][i]==fa)continue;
        dfs(e[k][i],k,d+1);
    }
    for(int i=0;i<v[k].size();i++)
    {
        add(d,-v[k][i].second);
        if(d+v[k][i].first+1<=n)add(d+v[k][i].first+1,v[k][i].second);
    }
}
int main()
{
    cin>>n;
    for(int i=1;i<n;i++)
    {
        int x,y;
        scanf("%d%d",&x,&y);
        e[x].push_back(y);
        e[y].push_back(x);
    }
    int m;
    cin>>m;
    while(m--)
    {
        int k,de,val;
        scanf("%d%d%d",&k,&de,&val);
        v[k].push_back({de,val});
    }
    dfs(1,0,1);
    for(int i=1;i<=n;i++)printf("%lld ",ans[i]);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/Mitsuha_/article/details/84027193
今日推荐