Submission #1182195

#TimeUsernameProblemLanguageResultExecution timeMemory
1182195CyanmondPetrol stations (CEOI24_stations)C++20
0 / 100
68 ms13896 KiB
#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 timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...