CF1076E 题解
感觉有点思维。
在搜索的时候记录当前的答案 \(now\)。对于当前点 \(u\) 的操作 \((d,x)\),先将 \(now\) 加上 \(x\) 往下传,同时在深度 \(dep_u+d+1\) 的地方打上标记,遍历到标记的深度时去除 \(x\) 对 \(now\) 的贡献。回溯的时候把标记清掉避免对后续子树造成影响即可。
#include<bits/stdc++.h>
#define int long long
#define pii pair<int,int>
#define fi first
#define se second
using namespace std;
const int N=3e5+5;
int n,m,dat[N],dep[N],ans[N];
vector<int>v[N];
vector<pii>g[N];
void dfs(int x,int fa,int now){
dep[x]=dep[fa]+1,now+=dat[dep[x]];
for(auto it:g[x]){
now+=it.se;
if(it.fi+dep[x]+1<=n)dat[it.fi+dep[x]+1]-=it.se;
}
ans[x]=now;
for(auto to:v[x])if(to!=fa)dfs(to,x,now);
for(auto it:g[x])if(it.fi+dep[x]+1<=n)dat[it.fi+dep[x]+1]+=it.se;
return;
}
signed main(){
ios::sync_with_stdio(0);
cin.tie(0),cout.tie(0);
cin>>n;
for(int i=1,x,y;i<n;i++){
cin>>x>>y;
v[x].push_back(y);
v[y].push_back(x);
}
cin>>m;
for(int i=1,x,y,z;i<=m;i++)
cin>>x>>y>>z,g[x].push_back({y,z});
dfs(1,0,0);
for(int i=1;i<=n;i++)cout<<ans[i]<<" ";
return 0;
}

浙公网安备 33010602011771号