#include <bits/stdc++.h>
using namespace std;
using ll = long long;
void solve() {
int n;
ll k;
cin >> n >> k;
vector<vector<pair<int, ll>>> g(n);
for (int i = 0; i < n - 1; ++i) {
int u, v;
ll w;
cin >> u >> v >> w;
g[u].push_back({v, w});
g[v].push_back({u, w});
}
// centroid decomposition
vector<bool> seen(n);
vector<int> sub_size(n);
auto find_size = [&](auto &&self, int v, int p) -> int {
sub_size[v] = 1;
for (auto &[t, w] : g[v]) if (t != p and not seen[t]) {
auto res = self(self, t, v);
sub_size[v] += res;
}
return sub_size[v];
};
auto find_centroid = [&](auto &&self, int v, int p, int s) -> int {
bool is_centroid = (s - sub_size[v]) <= s / 2;
for (auto &[t, w] : g[v]) if (t != p and not seen[t]) {
auto res = self(self, t, v, s);
if (res != -1) {
return res;
}
if (res > s / 2) {
res = false;
}
}
return is_centroid ? v : -1;
};
vector<ll> ans(n);
// subtask 5
static constexpr int D = 10;
using Data = array<int, D + 1>;
auto dfs1 = [&](auto &&self, int v, int p, int cof) -> Data {
Data ret;
fill(ret.begin(), ret.end(), 0);
ret[k] = 1;
for (auto &[t, w] : g[v]) if (t != p and not seen[t]) {
auto res = self(self, t, v, cof);
int sum_w = accumulate(res.begin(), res.begin() + w, 0);
for (int i = 0; i <= k - w; ++i) {
res[i] = res[i + w];
}
fill(res.begin() + (k - w) + 1, res.end(), 0);
res[k - w] += sum_w;
for (int i = 0; i <= k; ++i) {
ret[i] += res[i];
}
ans[t] += ll(sum_w) * cof;
}
return ret;
};
auto dfs2 = [&](auto &&self, int v, int p, Data pbase) -> void {
ll w_par = 0;
for (auto &[t, w] : g[v]) if (t == p) {
w_par = w;
break;
}
int sum_w = accumulate(pbase.begin(), pbase.begin() + w_par, 0);
for (int i = 0; i <= k - w_par; ++i) {
pbase[i] = pbase[i + w_par];
}
fill(pbase.begin() + (k - w_par) + 1, pbase.end(), 0);
pbase[k - w_par] += sum_w;
ans[p] += ll(sum_w) * sub_size[v];
for (auto &[t, w] : g[v]) if (t != p and not seen[t]) {
self(self, t, v, pbase);
}
};
auto cent_decomp = [&](auto &&self, int root) -> void {
// find centroid
const int s = find_size(find_size, root, -1);
const int cent = find_centroid(find_centroid, root, -1, s);
find_size(find_size, cent, -1);
// do process
vector<Data> ds(int(g[cent].size()));
Data r_sum;
fill(r_sum.begin(), r_sum.end(), 0);
r_sum[k] = 1;
for (int i = 0; i < int(g[cent].size()); ++i) {
auto &[t, w] = g[cent][i];
if (seen[t]) {
continue;
}
int cof = s - sub_size[t];
auto res = dfs1(dfs1, t, cent, cof);
int sum_w = accumulate(res.begin(), res.begin() + w, 0);
for (int i = 0; i <= k - w; ++i) {
res[i] = res[i + w];
}
fill(res.begin() + (k - w) + 1, res.end(), 0);
res[k - w] += sum_w;
ds[i] = res;
for (int i = 0; i <= k; ++i) {
r_sum[i] += res[i];
}
ans[t] += ll(sum_w) * cof;
}
for (int i = 0; i < int(g[cent].size()); ++i) {
auto &[t, w] = g[cent][i];
if (seen[t]) {
continue;
}
auto pbase = r_sum;
for (int j = 0; j <= k; ++j) {
pbase[j] -= ds[i][j];
}
dfs2(dfs2, t, cent, pbase);
}
seen[cent] = true;
for (auto &[t, w] : g[root]) if (not seen[t]) {
self(self, t);
}
};
cent_decomp(cent_decomp, 0);
for (auto e : ans) {
cout << e << '\n';
}
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
cout.tie(nullptr);
solve();
return 0;
}
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |