CF edu54 E
阿新 • • 發佈:2018-11-14
題意是給你一棵樹,m次操作,每次操作將點v的子樹中深度小於等於d的點加x,這道題的點是隻將子樹中符合條件的相加,所以可以直接樹上差分
#include<bits/stdc++.h> using namespace std; using LL = int64_t; const int maxn=3e5+5; LL ans[maxn],dep[maxn],now=0; vector<pair<int,LL>>Q[maxn]; vector<int>E[maxn]; int h=-1; void dfs(int x,int fa) { h++; now+=dep[h]; for(int i=0;i<Q[x].size();i++) { int nowd=Q[x][i].first,nowx=Q[x][i].second; now+=nowx; if(h+nowd+1<maxn) dep[h+nowd+1]-=nowx; } ans[x]+=now; for(int i=0;i<E[x].size();i++) { int v=E[x][i]; if(v!=fa) dfs(v,x); } for(int i=0;i<Q[x].size();i++) { int nowd=Q[x][i].first,nowx=Q[x][i].second; now-=nowx; if(h+nowd+1<maxn) dep[h+nowd+1]+=nowx; } now-=dep[h]; h--; } int main() { ios::sync_with_stdio(0); cin.tie(0);cout.tie(0); int n;cin>>n; for(int i=1;i<n;i++) { int x,y;cin>>x>>y; E[x].push_back(y); E[y].push_back(x); } int m;cin>>m; for(int i=1;i<=m;i++) { int u,d,x;cin>>u>>d>>x; Q[u].push_back({d,x}); } dfs(1,0); for(int i=1;i<=n;i++) cout<<ans[i]<<' '; return 0; }