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;
}
posted @ 2025-10-17 15:14  xuchuhan  阅读(6)  评论(0)    收藏  举报