제출 #1365813

#제출 시각아이디문제언어결과실행 시간메모리
1365813madamadam3BOI Acronym (BOI25_boi)C++20
0 / 100
0 ms344 KiB
#include <bits/stdc++.h>
using namespace std;

struct DSU {
    int n; vector<int> par, sz;
    DSU(int n = 0) : n(n), par(n, -1), sz(n, 1) {}
    int find(int v) {return par[v] == -1 ? v : par[v] = find(par[v]);}
    void unite(int a, int b) {
        a = find(a); b = find(b);
        if (a != b) {
            // if (sz[a] < sz[b]) swap(a,b);
            sz[a] += sz[b]; par[b] = a;
        }
    }
};

int main() {
    cin.tie(0)->sync_with_stdio(0);

    int n; cin >> n;
    vector<vector<int>> a(n, vector<int>(n));
    for (int i = 0; i < n; i++) for (int j = i; j < n; j++) cin >> a[i][j];

    int x = 0, c = 1;
    for (int j = 1; j < n; j++) {
        if (a[x][j-1] < a[x][j]) c++;
        else c--;

        if (c == 0) {
            x = j; c = 1;
        }
    }

    // x is now a guaranteed blue element
    // we know whether an element is equal to its neighbour or not, that is easy
    // so we have a bunch of little islands xyzxyzxyz and we need to determine whether 
    // or not x and z are equal (or not)
    // if |x| > |y|, then the test is easy
    // what about BOIBOIBOIBOI

    vector<int> cnt(1, a[0][n-1]);
    if (cnt[0] == n) {
        for (int i = 1; i <= n; i++) cout << i << " ";
        cout << "\n";
        return 0;
    }

    int p = 1; while (a[p-1][p-1] < a[p-1][p]) p++;
    cnt.push_back(a[p][n-1]);

    if (cnt[0] + cnt[1] == n) {
        auto dsu = DSU(n);
        for (int i = 0; i < n-1; i++) {
            if (a[i][i] < a[i][i+1]) dsu.unite(i, i+1);
        }

        int p = 0;
        vector<int> p1, p2;
        for (int i = 0; i < n; i++) {
            if (i > 0 && dsu.find(i) != dsu.find(i-1)) p = 1-p;
            if (p == 0) p1.push_back(i+1);
            else p2.push_back(i+1);
        }
        
        if (p1.size() < p2.size()) swap(p1, p2);
        for (auto x : p1) cout << x << " "; cout << "\n";
        return 0;
    }

    cnt.push_back(n-cnt[0]-cnt[1]);
    auto dsu = DSU(n);
    for (int i = 0; i < n-1; i++) {
        if (a[i][i+1] == 2) dsu.unite(i, i+1);
    }

    auto block = [&](int i) {
        int j = i; while (j < n && a[i][j] == j-i+1) j++;
        return j-1;
    };

    for (int i = 0; i < n; i++) {
        int m = block(i)+1;
        if (m >= n) break;
        int r = block(m)+1;
        if (r >= n) break;
        int k = block(r);
        if (a[i][k] > max({m-i, r-m, k-r+1})) dsu.unite(i, r);

        i = m-1;
    }

    int g = dsu.find(0); for (int i = 1; i < n; i++) if (dsu.sz[dsu.find(i)] > dsu.sz[g]) g = dsu.find(i);
    for (int i = 0; i < n; i++) {
        if (dsu.find(i) == g) cout << i+1 << " ";
    }
    return 0;
}
#결과 실행 시간메모리채점기 출력
결과를 불러오는 중입니다…
#결과 실행 시간메모리채점기 출력
결과를 불러오는 중입니다…
#결과 실행 시간메모리채점기 출력
결과를 불러오는 중입니다…
#결과 실행 시간메모리채점기 출력
결과를 불러오는 중입니다…
#결과 실행 시간메모리채점기 출력
결과를 불러오는 중입니다…
#결과 실행 시간메모리채점기 출력
결과를 불러오는 중입니다…
#결과 실행 시간메모리채점기 출력
결과를 불러오는 중입니다…