Vasya and a Tree [contest/1076 E]
阿新 • • 發佈:2018-11-22
Vasya and a Tree [contest/1076 E]
題面
思路
看到修改一個子樹內容,第一反應是打標記,但由於只修改深度範圍內的節點,容易想到用類似差分的思想去做。說到差分那首選就是樹狀陣列了,維護每個節點的修改情況,進入節點時,將拆分內容加入線段樹,出該節點時恢復差分情況即可
程式碼
int n,m;
vector<int>G[maxn];
vector<pair<int,int> >update[maxn];
int dep[maxn];
ll tree[maxn],ans[maxn];
void add (int u,ll c){
while(u<=n){
tree[u]+=c;
u+=lowbit(u);
}
}
ll query(int u){
ll ans=0;
while(u){
ans+=tree[u];
u-=lowbit(u);
}
return ans;
}
void dfs(int u,int f,int d){
dep[u]=d;
rep(i,0,update[u].size()){
add(dep[u],update[u][i] .second);
add(dep[u]+update[u][i].first+1,-update[u][i].second);
}
ans[u]=query(dep[u]);
rep(i,0,G[u].size()){
int v=G[u][i];
if(v==f)continue;
dfs(v,u,d+1);
}
rep(i,0,update[u].size()){
add(dep[u],-update[u][i].second);
add(dep[u]+update[ u][i].first+1,update[u][i].second);
}
}
int main(){
rd(n);
rep(i,1,n){
int a,b;
rd(a,b);
G[a].pb(b);G[b].pb(a);
}
rd(m);
rep(i,0,m){
int a,b,c;
rd(a,b,c);
update[a].pb(mp(b,c));
}
dfs(1,-1,1);
rep(i,1,n+1)
printf("%lld ",ans[i]);
}