Submission #1274156

#TimeUsernameProblemLanguageResultExecution timeMemory
1274156IcelastReconstruction Project (JOI22_reconstruction)C++20
70 / 100
5109 ms404596 KiB
#include <bits/stdc++.h>
using namespace std;
using ll = long long;

struct DSU {
    int maxn;
    vector<int> pa;
    vector<int> sz;

    DSU(int maxn = 0) { init(maxn); }

    void init(int _maxn) {
        maxn = _maxn;
        if ((int)pa.size() < maxn + 5) {
            pa.resize(maxn + 5);
            sz.resize(maxn + 5);
        }
        reset(maxn);
    }

    // reset to fresh DSU of size n (1..n)
    void reset(int n) {
        // note: loop is necessary (same complexity as original) but avoids reallocations
        for (int i = 0; i <= n; ++i) {
            pa[i] = i;
            sz[i] = 1;
        }
    }

    int find(int x) {
        while (x != pa[x]) {
            pa[x] = pa[pa[x]];
            x = pa[x];
        }
        return x;
    }

    bool merge(int x, int y) {
        x = find(x);
        y = find(y);
        if (x == y) return false;
        if (sz[x] < sz[y]) swap(x, y);
        pa[y] = x;
        sz[x] += sz[y];
        return true;
    }

    bool same(int x, int y) { return find(x) == find(y); }
    int size(int x) { return sz[find(x)]; }
};

struct Edge {
    int u, v;
    int w;
};

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    int n, m;
    if (!(cin >> n >> m)) return 0;

    vector<Edge> e(m + 1);
    for (int i = 1; i <= m; ++i) {
        cin >> e[i].u >> e[i].v >> e[i].w;
    }

    sort(e.begin() + 1, e.end(), [](const Edge &a, const Edge &b) {
        return a.w < b.w;
    });

    // preallocate lt/rt
    vector<vector<int>> lt(m + 1), rt(m + 1);

    DSU dsu(n); // allocate once
    dsu.init(n);

    // build lt (1..m), lt[0] stays empty
    for (int i = 1; i <= m; ++i) {
        dsu.reset(n);
        dsu.merge(e[i].u, e[i].v);

        lt[i].reserve((i > 0 ? lt[i - 1].size() : 0) + 1);
        lt[i].push_back(i);

        const auto &prev = lt[i - 1];
        for (int it : prev) {
            if (dsu.merge(e[it].u, e[it].v)) lt[i].push_back(it);
        }
    }

    // build rt ; rt[m] stays empty in original logic (we mirror original indexing)
    for (int i = m; i >= 1; --i) {
        dsu.reset(n);
        dsu.merge(e[i].u, e[i].v);

        rt[i - 1].reserve((i <= m ? rt[i].size() : 0) + 1);
        rt[i - 1].push_back(i);

        const auto &next = rt[i];
        for (int it : next) {
            if (dsu.merge(e[it].u, e[it].v)) rt[i - 1].push_back(it);
        }
    }

    int Q;
    cin >> Q;
    int p = 0; // number of edges with weight <= x (keeps same meaning as your original code)
    for (int qi = 0; qi < Q; ++qi) {
        int x;
        cin >> x;
        while (p + 1 <= m && e[p + 1].w <= x) ++p;

        dsu.reset(n);
        ll ans = 0;

        const auto &L = lt[p];
        const auto &R = rt[p];
        int p1 = 0, p2 = 0;
        int total = (int)L.size() + (int)R.size();

        // merge edges in the order you had (closest weight to x first)
        for (int t = 0; t < total; ++t) {
            if (p2 == (int)R.size() || (p1 < (int)L.size() && ll(x - e[L[p1]].w) <= ll(e[R[p2]].w - x))) {
                int idx = L[p1++];
                if (dsu.merge(e[idx].u, e[idx].v)) ans += ll(x - e[idx].w);
            } else {
                int idx = R[p2++];
                if (dsu.merge(e[idx].u, e[idx].v)) ans += ll(e[idx].w - x);
            }
        }

        cout << ans << '\n';
    }

    return 0;
}
//chatgpt test
#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...