QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#513279 | #9170. Cycle Game | ucup-team133# | WA | 0ms | 3788kb | C++23 | 5.6kb | 2024-08-10 17:24:16 | 2024-08-10 17:24:16 |
Judging History
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'