Submission #1348685

#TimeUsernameProblemLanguageResultExecution timeMemory
1348685truongdz_top12Stranded Far From Home (BOI22_island)C++20
0 / 100
430 ms55612 KiB
#include <bits/stdc++.h>
using namespace std;

using ll = long long;

struct DSU {
    vector<int> p;
    DSU() {}
    DSU(int n) { init(n); }
    void init(int n) {
        p.resize(n + 1);
        iota(p.begin(), p.end(), 0);
    }
    int find(int x) {
        int r = x;
        while (p[r] != r) r = p[r];
        while (p[x] != x) {
            int y = p[x];
            p[x] = r;
            x = y;
        }
        return r;
    }
};

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

    int n, m;
    cin >> n >> m;

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

    vector<vector<int>> adj(n + 1);
    for (int i = 0; i < m; ++i) {
        int a, b;
        cin >> a >> b;
        adj[a].push_back(b);
        adj[b].push_back(a);
    }

    vector<int> ord(n);
    iota(ord.begin(), ord.end(), 1);
    sort(ord.begin(), ord.end(), [&](int a, int b) {
        if (s[a] != s[b]) return s[a] < s[b];
        return a < b;
    });

    int maxNodes = 2 * n + 5;
    DSU dsu(maxNodes);

    vector<ll> sum(maxNodes, 0), mx(maxNodes, 0);
    vector<int> parent(maxNodes, 0), seen(maxNodes, 0);
    vector<char> active(n + 1, 0);

    for (int i = 1; i <= n; ++i) {
        sum[i] = s[i];
        mx[i] = s[i];
    }

    int tot = n, timer = 0;

    for (int v : ord) {
        active[v] = 1;
        ++timer;
        vector<int> roots;
        for (int to : adj[v]) {
            if (!active[to]) continue;
            int r = dsu.find(to);
            if (seen[r] != timer) {
                seen[r] = timer;
                roots.push_back(r);
            }
        }

        if (roots.empty()) continue;

        ++tot;
        dsu.p[tot] = tot;
        sum[tot] = s[v];
        mx[tot] = s[v];
        parent[tot] = 0;

        for (int r : roots) {
            parent[r] = tot;
            dsu.p[r] = tot;
            sum[tot] += sum[r];
        }

        parent[v] = tot;
        dsu.p[v] = tot;
        sum[tot] += s[v];
    }

    int root = dsu.find(1);
    int LOG = 1;
    while ((1 << LOG) <= tot) ++LOG;
    vector<vector<int>> up(LOG, vector<int>(tot + 1, 0));
    for (int i = 1; i <= tot; ++i) up[0][i] = parent[i];
    for (int k = 1; k < LOG; ++k) {
        for (int i = 1; i <= tot; ++i) {
            up[k][i] = up[k - 1][up[k - 1][i]];
        }
    }

    auto climb = [&](int x, ll lim) {
        for (int k = LOG - 1; k >= 0; --k) {
            int y = up[k][x];
            if (y && mx[y] <= lim) x = y;
        }
        return x;
    };

    vector<int> nxt(tot + 1);
    for (int i = 1; i <= tot; ++i) {nxt[i] = climb(i, sum[i]);cerr<<nxt[i]<<' ';}

    vector<char> good(tot + 1, 0);
    vector<int> nodes(tot);
    iota(nodes.begin(), nodes.end(), 1);
    sort(nodes.begin(), nodes.end(), [&](int a, int b) {
        if (sum[a] != sum[b]) return sum[a] > sum[b];
        return a < b;
    });

    for (int x : nodes) {
        if (nxt[x] == x) good[x] = (x == root);
        else good[x] = good[nxt[x]];
    }

    string ans;
    ans.reserve(n);
    for (int i = 1; i <= n; ++i) ans.push_back(good[i] ? '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...