QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#513279#9170. Cycle Gameucup-team133#WA 0ms3788kbC++235.6kb2024-08-10 17:24:162024-08-10 17:24:16

Judging History

你现在查看的是最新测评结果

  • [2024-08-10 17:24:16]
  • 评测
  • 测评结果:WA
  • 用时:0ms
  • 内存:3788kb
  • [2024-08-10 17:24:16]
  • 提交

answer

#include <bits/stdc++.h>
#ifdef LOCAL
#include <debug.hpp>
#else
#define debug(...) void(0)
#endif

template <class T> std::istream& operator>>(std::istream& is, std::vector<T>& v) {
    for (auto& e : v) {
        is >> e;
    }
    return is;
}

template <class T> std::ostream& operator<<(std::ostream& os, const std::vector<T>& v) {
    for (std::string_view sep = ""; const auto& e : v) {
        os << std::exchange(sep, " ") << e;
    }
    return os;
}

template <class T, class U = T> bool chmin(T& x, U&& y) {
    return y < x and (x = std::forward<U>(y), true);
}

template <class T, class U = T> bool chmax(T& x, U&& y) {
    return x < y and (x = std::forward<U>(y), true);
}

template <class T> void mkuni(std::vector<T>& v) {
    std::ranges::sort(v);
    auto result = std::ranges::unique(v);
    v.erase(result.begin(), result.end());
}

template <class T> int lwb(const std::vector<T>& v, const T& x) {
    return std::distance(v.begin(), std::ranges::lower_bound(v, x));
}

struct UndoUnionFind {
    UndoUnionFind() {}

    UndoUnionFind(int n) : n(n), data(n, -1) {}

    int find(int x) const {
        assert(0 <= x && x < n);
        return data[x] < 0 ? x : find(data[x]);
    }

    bool merge(int x, int y) {
        assert(0 <= x && x < n);
        assert(0 <= y && y < n);
        x = find(x), y = find(y);
        history.emplace(x, data[x]);
        history.emplace(y, data[y]);
        if (x == y) return false;
        if (-data[x] < -data[y]) std::swap(x, y);
        data[x] += data[y];
        data[y] = x;
        return true;
    }

    bool same(int x, int y) const {
        assert(0 <= x && x < n);
        assert(0 <= y && y < n);
        return find(x) == find(y);
    }

    int size(int x) const {
        assert(0 <= x && x < n);
        return -data[find(x)];
    }

    void undo() {
        assert(!history.empty());
        data[history.top().first] = history.top().second;
        history.pop();
        data[history.top().first] = history.top().second;
        history.pop();
    }

    void snapshot() {
        while (!history.empty()) history.pop();
    }

    void rollback() {
        while (!history.empty()) undo();
    }

    int operator[](int x) const { return find(x); }

  private:
    int n;
    std::vector<int> data;
    std::stack<std::pair<int, int>> history;
};

using ll = long long;

using namespace std;

constexpr int dx[4] = {1, 0, -1, 0}, dy[4] = {0, 1, 0, -1};

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    cout << fixed << setprecision(15);
    int n, m, k;
    cin >> n >> m >> k;

    vector S(n, vector<bool>(m, false));
    UndoUnionFind uf(n * m);
    auto isin = [&](int x, int y) { return 0 <= x and x < n and 0 <= y and y < m; };
    auto id = [&](int x, int y) { return x * m + y; };
    stack<tuple<int, int, int>> st;
    vector<int> es(n * m, 0), mass(n * m, 0);
    auto f = [&](int r, int c) {
        S[r][c] = true;
        for (int i = 0; i < 4; i++) {
            int nx = r + dx[i], ny = c + dy[i];
            if (not isin(nx, ny)) continue;
            if (not S[nx][ny]) continue;
            int u = id(r, c), v = id(nx, ny);
            u = uf.find(u), v = uf.find(v);
            st.emplace(nx, es[u], mass[v]);
            st.emplace(ny, es[u], mass[v]);
            uf.merge(u, v);
            if (u != v) {
                int w = uf.find(u);
                es[w] = es[u] + es[v] + 1;
                mass[w] = mass[u] + mass[v];
            } else {
                es[u]++;
            }
        }
    };
    auto g = [&](int r, int c) {
        S[r][c] = false;
        for (int i = 3; i >= 0; i--) {
            int nx = r + dx[i], ny = c + dy[i];
            if (not isin(nx, ny)) continue;
            if (not S[nx][ny]) continue;
            for (int _ = 0; _ < 2; _++) {
                auto [idx, e, m] = st.top();
                st.pop();
                es[idx] = e;
                mass[idx] = m;
            }
            uf.undo();
        }
    };
    auto three = [&](int x, int y) {  // (x, y) を中心とする 3 * 3 領域が black か
        for (int ddx = -1; ddx <= 1; ddx++) {
            for (int ddy = -1; ddy <= 1; ddy++) {
                int nx = x + ddx, ny = y + ddy;
                if (not isin(nx, ny)) return false;
                if (not S[nx][ny]) return false;
            }
        }
        return true;
    };
    auto two = [&](int x, int y) {  // (x, y) を左上とする 2 * 2 領域が black か
        for (int ddx = 0; ddx <= 1; ddx++) {
            for (int ddy = 0; ddy <= 1; ddy++) {
                int nx = x + ddx, ny = y + ddy;
                if (not isin(nx, ny)) return false;
                if (not S[nx][ny]) return false;
            }
        }
        return true;
    };
    auto query = [&](int r, int c) -> bool {
        for (int ddx = -1; ddx <= 1; ddx++) {
            for (int ddy = -1; ddy <= 1; ddy++) {
                int nx = r + ddx, ny = c + ddy;
                if (three(nx, ny)) return false;
            }
        }
        int root = uf.find(id(r, c));
        for (int ddx = -1; ddx <= 0; ddx++) {
            for (int ddy = -1; ddy <= 0; ddy++) {
                int nx = r + ddx, ny = c + ddy;
                if (two(nx, ny)) mass[root]++;
            }
        }
        // debug(es[root], mass[root], uf.size(root));
        if (es[root] - mass[root] >= uf.size(root)) return false;
        return true;
    };

    for (; k--;) {
        int r, c;
        cin >> r >> c;
        r--, c--;
        f(r, c);
        if (query(r, c)) {
            cout << "1";
        } else {
            cout << "0";
            g(r, c);
        }
    }
    cout << "\n";
    return 0;
}

Details

Tip: Click on the bar to expand more detailed information

Test #1:

score: 100
Accepted
time: 0ms
memory: 3552kb

input:

4 3 7
2 1
2 2
2 3
3 1
3 2
4 1
4 2

output:

1111111

result:

ok "1111111"

Test #2:

score: 0
Accepted
time: 0ms
memory: 3528kb

input:

3 3 8
1 1
1 2
1 3
2 3
3 3
3 2
3 1
2 1

output:

11111110

result:

ok "11111110"

Test #3:

score: 0
Accepted
time: 0ms
memory: 3584kb

input:

10 10 7
9 1
6 6
3 8
8 7
5 10
1 7
1 2

output:

1111111

result:

ok "1111111"

Test #4:

score: 0
Accepted
time: 0ms
memory: 3756kb

input:

9 10 50
1 9
1 6
2 3
3 1
7 4
9 4
1 3
2 5
9 2
7 9
5 6
8 10
9 5
5 5
4 10
9 7
5 9
3 2
4 5
1 1
4 7
3 6
2 8
4 3
8 6
5 10
4 8
5 4
7 2
9 6
4 2
7 8
5 2
3 5
9 1
6 1
1 5
9 9
5 8
6 3
8 8
8 4
7 7
7 1
3 7
2 2
3 10
6 9
8 3
7 6

output:

11111111111111111111111111111111111111111111111111

result:

ok "11111111111111111111111111111111111111111111111111"

Test #5:

score: 0
Accepted
time: 0ms
memory: 3528kb

input:

3 5 11
1 5
2 4
1 2
1 3
3 3
3 1
3 4
2 3
1 4
2 1
2 5

output:

11111111111

result:

ok "11111111111"

Test #6:

score: 0
Accepted
time: 0ms
memory: 3788kb

input:

7 9 12
7 3
2 3
6 2
2 2
4 2
2 8
5 7
4 4
6 8
2 7
7 2
1 9

output:

111111111111

result:

ok "111111111111"

Test #7:

score: 0
Accepted
time: 0ms
memory: 3540kb

input:

1 4 1
1 2

output:

1

result:

ok "1"

Test #8:

score: -100
Wrong Answer
time: 0ms
memory: 3572kb

input:

9 8 67
5 5
8 3
9 5
7 4
5 1
9 3
4 2
2 5
1 7
7 8
7 2
8 5
6 1
8 8
4 4
5 4
1 5
3 4
6 7
2 3
3 7
5 7
2 4
2 7
1 3
7 3
2 8
6 6
6 2
6 3
7 5
9 6
7 6
3 6
1 1
6 4
3 1
5 3
8 7
2 1
4 1
8 4
8 6
3 5
5 8
1 6
1 2
4 6
9 4
1 4
3 3
4 8
8 1
4 7
9 8
3 8
6 5
6 8
3 2
2 2
7 1
9 2
4 3
1 8
4 5
8 2
7 7

output:

1111111111111111111111111111111111111111111110000000100000000000000

result:

wrong answer 1st words differ - expected: '111111111111111111111111111111...1111111110010101101000101101101', found: '111111111111111111111111111111...1111111110000000100000000000000'