这道题正解是KD-Tree或者一个奇妙的递归思路。因为我太菜了,这里只能提供一种部分分做法。
首先对树进行dfs,对于每个节点(u),维护出其dfs序和深度,这里用(dfn_u)表示其dfs序,(dep_u)表示其深度,(end_u)表示离开子树的时间((end_u = dfn_u + siz_u))。
对一个节点的d级子树进行修改,其实就是找到所有节点(v),满足(dfn_u leq dfn_v leq end_u)以及(dep_u leq dep_v leq dep_u + d)。那么我们不妨将每个节点用一个二元组((dfn_u,dep_u))表示,在平面内,每次修改相当于是找到一个左下角是((dfn_u,dep_u)),右上角是((end_u,dep_u + d))的矩形,将这个矩形内部所有点加上一个权值。而我因为不会KD-Tree,只好用二维树状数组维护,但是这里的空间复杂度高达(O(n imes maxdep)),如果树较为平衡则可过,但是若树退化成一条链则这个算法会爆空间。
放一个部分分代码随便搞搞qwq。
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<cstdlib>
#include<vector>
#include<set>
#include<map>
#include<string>
#include<iostream>
#include<queue>
#include<cctype>
using namespace std;
#define A(x) cout << #x << " " << x << endl;
#define AA(x,y) cout << #x << " " << x << #y << " " << y << endl;
#define B cout << "Break" << endl;
#define ll long long
#define inf 1000000000
int read()
{
int c = getchar();
int x = 0,f = 1;
while(!isdigit(c))
{
if(c == '-') f = -1;
c = getchar();
}
while(isdigit(c))
{
x = x * 10 + c - '0';
c = getchar();
}
return f * x;
}
#define N 300010
vector<int>g[N];
int dfn[N],dep[N],til[N];
int n,m,maxdep,tim;
void dfs(int u,int fa)
{
dfn[u] = ++tim;
dep[u] = dep[fa] + 1;
maxdep = max(dep[u],maxdep);
for(auto v : g[u])
{
if(v == fa) continue;
dfs(v,u);
}
til[u] = tim;
return;
}
int c[N][250];
int lowbit(int x)
{
return x & -x;
}
void Add(int x,int y,int k)
{
for(int i = x;i <= n;i += lowbit(i))
for(int j = y;j <= maxdep;j += lowbit(j))
c[i][j] += k;
return;
}
void add(int xa,int ya,int xb,int yb,int k)
{
Add(xa,ya,k);
Add(xa,yb + 1,-k);
Add(xb + 1,ya,-k);
Add(xb + 1,yb + 1,k);
return;
}
int query(int x,int y)
{
int ret = 0;
for(int i = x;i > 0;i -= lowbit(i))
for(int j = y;j > 0;j -= lowbit(j))
ret += c[i][j];
return ret;
}
int main()
{
n = read();
for(int i = 1;i < n;++i)
{
int u = read(),v = read();
g[u].push_back(v);
g[v].push_back(u);
}
dfs(1,0);
m = read();
while(m--)
{
int u = read(),d = read(),k = read();
add(dfn[u],dep[u],til[u],dep[u] + d,k);
}
for(int i = 1;i <= n;++i)
{
printf("%d ",query(dfn[i],dep[i]));
}
}