Codeforces - Vasya and a Tree

題目鏈接:Codeforces - Vasya and a Tree


如果是簡單的子樹加減,那麼直接dfs序+Fenwick就可以解決。

現在,子樹加上了一個深度的限制。我們似乎可以從上到下,用主席樹合併答案。實際上也是可以的。

但是我們有一個簡單的做法,就是利用dfs,每次進入子樹的時候維護Fenwick,出子樹的時候清除影響,就利用小空間達到和主席樹一樣的效果了。


AC代碼:

#pragma GCC optimize("-Ofast","-funroll-all-loops")
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=3e5+10;
int n,m,res[N],d[N],dep[N];
vector<int> g[N];	vector<pair<int,int>> v[N];
inline void add(int a,int b){g[a].push_back(b),g[b].push_back(a);}
inline void insert(int x,int v){for(;x<=n;x+=x&(-x)) d[x]+=v;}
inline int ask(int x){int s=0; for(;x;x-=x&(-x)) s+=d[x]; return s;}
void dfs(int x,int fa){
	dep[x]=dep[fa]+1;
	for(auto to:v[x])	insert(dep[x],to.second),insert(dep[x]+to.first+1,-to.second);
	res[x]=ask(dep[x]);
	for(auto to:g[x])	if(to!=fa)	dfs(to,x);
	for(auto to:v[x])	insert(dep[x],-to.second),insert(dep[x]+to.first+1,to.second);
}
signed main(){
	cin>>n;
	for(int i=1,x,y;i<n;i++)	scanf("%lld %lld",&x,&y),add(x,y);
	cin>>m;
	for(int i=1,p,d,x;i<=m;i++)	scanf("%lld %lld %lld",&p,&d,&x),v[p].push_back({d,x});
	dfs(1,1);
	for(int i=1;i<=n;i++)	printf("%lld ",res[i]);
	return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章