Submission #1348692

#TimeUsernameProblemLanguageResultExecution timeMemory
1348692truongdz_top12Stranded Far From Home (BOI22_island)C++20
100 / 100
118 ms47808 KiB
#include <bits/stdc++.h>
using namespace std;

using ll = long long;

struct Edge {
    ll t;
    int u, v;
    bool operator<(const Edge& other) const { return t < other.t; }
};

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

    int N, M;
    if (!(cin >> N >> M)) return 0;

    vector<ll> s(N + 1);
    for (int i = 1; i <= N; ++i) cin >> s[i];

    vector<Edge> edges;
    edges.reserve(M);
    for (int i = 0; i < M; ++i) {
        int u, v;
        cin >> u >> v;
        edges.push_back({max(s[u], s[v]), u, v});
    }
    sort(edges.begin(), edges.end());

    int maxNodes = 2 * N + 5;
    vector<int> fa(maxNodes), par(maxNodes);
    vector<ll> key(maxNodes), sum(maxNodes);

    for (int i = 1; i <= N; ++i) {
        fa[i] = i;
        key[i] = sum[i] = s[i];
    }

    auto find_root = [&](int x) {
        int r = x;
        while (fa[r] != r) r = fa[r];
        while (fa[x] != x) {
            int p = fa[x];
            fa[x] = r;
            x = p;
        }
        return r;
    };

    int cnt = N;
    for (const auto& e : edges) {
        int ru = find_root(e.u), rv = find_root(e.v);
        if (ru == rv) continue;
        ++cnt;
        key[cnt] = e.t;
        sum[cnt] = sum[ru] + sum[rv];
        par[ru] = par[rv] = cnt;
        fa[ru] = fa[rv] = cnt;
        fa[cnt] = cnt;
    }

    int root = find_root(1);

    int LOG = 1;
    while ((1 << LOG) <= cnt) ++LOG;

    vector<vector<int>> up(LOG, vector<int>(cnt + 1, 0));
    for (int i = 1; i <= cnt; ++i) up[0][i] = par[i];
    for (int j = 1; j < LOG; ++j) {
        for (int i = 1; i <= cnt; ++i) {
            int p = up[j - 1][i];
            up[j][i] = p ? up[j - 1][p] : 0;
        }
    }

    auto jump = [&](int x, ll th) {
        for (int j = LOG - 1; j >= 0; --j) {
            int y = up[j][x];
            if (y && key[y] <= th) x = y;
        }
        return x;
    };

    vector<int> nxt(cnt + 1), fin(cnt + 1, 0), st;
    st.reserve(cnt);

    for (int i = 1; i <= cnt; ++i) nxt[i] = jump(i, sum[i]);

    for (int i = 1; i <= cnt; ++i) {
        if (fin[i]) continue;
        int x = i;
        st.clear();
        while (!fin[x] && nxt[x] != x) {
            st.push_back(x);
            x = nxt[x];
        }
        int res = fin[x] ? fin[x] : x;
        if (!fin[x]) fin[x] = res;
        for (int j = (int)st.size() - 1; j >= 0; --j) fin[st[j]] = res;
    }

    string ans;
    ans.reserve(N);
    for (int i = 1; i <= N; ++i) {
        int start = jump(i, s[i]);
        ans.push_back(fin[start] == root ? '1' : '0');
    }

    cout << ans << '\n';
    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...