题目链接
题目大意:
给定一棵树,总共有m个操作,每个操作包括 v d k。
表示以v为根,在v的子树中所有深度
≤
\le
≤d+dep(v深度为dep)的节点权值都+k,最后输出每个顶点的权值。
解题思路:
对树进行dfs可以记录节点深度,每到一个节点,就把以当前节点为根的操作都进行一遍,例如当前深度为dep,就将Add[dep…dep+d]都+k,然后记录当前点的答案,但是dfs回溯的时候要将这些操作撤销,因为会变成处理另一棵子树了,就是将这些操作都变成-k重新操作一次就行了。对区间加减可以使用线段树或区间差分实现就行了。(代码中注释的是线段树操作,没注释的是区间差分,cin会T)。
解题代码:
#include<bits/stdc++.h>
using namespace std;
mt19937 rng_32(chrono::steady_clock::now().time_since_epoch().count());
typedef long long ll;
const ll maxn=3e5+10;
struct E{
ll to,nxt;
}e[maxn*2];
ll tot,head[maxn];
ll Add[maxn<<2],lz[maxn<<2];
void adde(ll u,ll v)
{
tot++;
e[tot]={v,head[u]};
head[u]=tot;
}
// void pushdown(ll x)
// {
// if (lz[x])
// {
// Add[x<<1]+=lz[x];
// Add[x<<1|1]+=lz[x];
// lz[x<<1]+=lz[x];
// lz[x<<1|1]+=lz[x];
// lz[x]=0;
// }
// }
// void update(ll l,ll r,ll i,ll ql,ll qr,ll add)
// {
// if (ql<=l && qr>=r)
// {
// Add[i]+=add;
// lz[i]+=add;
// return ;
// }
// pushdown(i);
// ll mid=(l+r)>>1;
// if (ql<=mid)
// update(l,mid,i<<1,ql,qr,add);
// if (qr>mid)
// update(mid+1,r,i<<1|1,ql,qr,add);
// return ;
// }
// ll query(ll l,ll r,ll i,ll pos)
// {
// if (l==r)
// {
// return Add[i];
// }
// pushdown(i);
// ll mid=(l+r)>>1;
// if (pos<=mid)
// return query(l,mid,i<<1,pos);
// else
// return query(mid+1,r,i<<1|1,pos);
// }
vector<pair<ll,ll> >v[maxn];
ll n;
ll ans[maxn];
void dfs(int u,int fa,int dep)
{
int len=v[u].size();
for (int i=0;i<len;i++)
{
int d=min(n+1,dep+v[u][i].first+1);
Add[dep]+=v[u][i].second;
Add[d]-=v[u][i].second;
// update(1,n,1,dep,min(n,dep+v[u][i].first),v[u][i].second);
}
Add[dep]+=Add[dep-1];
ans[u]=Add[dep];
//ans[u]=query(1,n,1,dep);
for (int i=head[u];i;i=e[i].nxt)
{
int to=e[i].to;
if (to==fa)
continue;
dfs(to,u,dep+1);
}
for (int i=0;i<len;i++)
{
int d=min(n+1,dep+v[u][i].first+1);
Add[dep]-=v[u][i].second;
Add[d]+=v[u][i].second;
// update(1,n,1,dep,min(n,dep+v[u][i].first),-1ll*v[u][i].second);
}
Add[dep]-=Add[dep-1];
}
int main()
{
cin>>n;
ll t1,t2;
for (ll i=1;i<n;i++)
{
scanf("%lld%lld",&t1,&t2);
adde(t1,t2);
adde(t2,t1);
}
ll m,t3;
cin>>m;
for (ll i=1;i<=m;i++)
{
scanf("%lld%lld%lld",&t1,&t2,&t3);
v[t1].push_back(make_pair(t2,t3));
}
dfs(1,1,1);
for (int i=1;i<=n;i++)
printf("%lld ",ans[i]);
return 0;
}