#include <bits/stdc++.h>
using namespace std;
#define FOR(i, l, r) for(int i = (l); i <= (r); ++i)
#define REP(i, n) FOR(i, 0, (n) - 1)
#define ssize(x) int(x.size())
#ifdef DEBUG
auto &operator << (auto &o, pair<auto, auto> p) {
return o << "(" << p.first << ", " << p.second << ")";
}
auto operator << (auto &o, auto x) -> decltype(x.end(), o) {
o << "{"; int i = 0;
for (auto e : x) o << ","+!i++ << e;
return o << "}";
}
ostream& operator << (ostream &o, vector<vector<bool>> board) {
o << '\n';
for (auto b : board) {
string row = "";
for (bool b_i : b)
row += (b_i ? "#" : ".");
o << row << '\n';;
}
return o;
}
#define debug(X...) cerr << "["#X"]: ", [](auto ...$) {((cerr << $ << "; "), ...) << endl;}(X)
#else
#define debug(...) {}
#endif
int n, m;
set<pair<int, int>> org_points;
vector<pair<int, int>> get_neis(int x, int y) {
return {
{x - 1, y},
{x + 1, y},
{x, y - 1},
{x, y + 1}
};
}
int solve() {
auto points = org_points;
auto exists = [&](int x, int y) {
return points.contains(pair(x, y));
};
auto can_be_taken = [&](int i, int j) {
if ((i == 0 or !exists(i - 1, j))
and (i == n - 1 or !exists(i + 1, j)))
return true;
if ((j == 0 or !exists(i, j - 1))
and (j == m - 1 or !exists(i, j + 1)))
return true;
return false;
};
deque<pair<int, int>> Q = {};
set<pair<int, int>> visited = {};
REP (i, n) REP (j, m) {
if (exists(i, j) and can_be_taken(i, j)) {
visited.emplace(i, j);
Q.emplace_back(i, j);
}
}
int answer = 0;
while (!Q.empty()) {
auto [i, j] = Q.front();
Q.pop_front();
points.erase(pair(i, j));
++answer;
for (auto [x, y] : get_neis(i, j)) {
if (x < 0 or x >= n or y < 0 or y >= m)
continue;
if (exists(x, y) and !visited.contains({x, y})
and can_be_taken(x, y)) {
visited.emplace(x, y);
Q.emplace_back(x, y);
}
}
}
return answer;
}
int main() {
ios_base::sync_with_stdio(0);
cin.tie(0);
int k, q;
cin >> n >> m >> k >> q;
REP (i, k) {
int x, y;
cin >> x >> y;
--x, --y;
org_points.emplace(x, y);
}
cout << solve() << '\n';
while (q--) {
int x, y;
cin >> x >> y;
--x, --y;
if (org_points.contains({x, y}))
org_points.erase({x, y});
else
org_points.emplace(x, y);
cout << solve() << '\n';
}
}
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 | #include <bits/stdc++.h> using namespace std; #define FOR(i, l, r) for(int i = (l); i <= (r); ++i) #define REP(i, n) FOR(i, 0, (n) - 1) #define ssize(x) int(x.size()) #ifdef DEBUG auto &operator << (auto &o, pair<auto, auto> p) { return o << "(" << p.first << ", " << p.second << ")"; } auto operator << (auto &o, auto x) -> decltype(x.end(), o) { o << "{"; int i = 0; for (auto e : x) o << ","+!i++ << e; return o << "}"; } ostream& operator << (ostream &o, vector<vector<bool>> board) { o << '\n'; for (auto b : board) { string row = ""; for (bool b_i : b) row += (b_i ? "#" : "."); o << row << '\n';; } return o; } #define debug(X...) cerr << "["#X"]: ", [](auto ...$) {((cerr << $ << "; "), ...) << endl;}(X) #else #define debug(...) {} #endif int n, m; set<pair<int, int>> org_points; vector<pair<int, int>> get_neis(int x, int y) { return { {x - 1, y}, {x + 1, y}, {x, y - 1}, {x, y + 1} }; } int solve() { auto points = org_points; auto exists = [&](int x, int y) { return points.contains(pair(x, y)); }; auto can_be_taken = [&](int i, int j) { if ((i == 0 or !exists(i - 1, j)) and (i == n - 1 or !exists(i + 1, j))) return true; if ((j == 0 or !exists(i, j - 1)) and (j == m - 1 or !exists(i, j + 1))) return true; return false; }; deque<pair<int, int>> Q = {}; set<pair<int, int>> visited = {}; REP (i, n) REP (j, m) { if (exists(i, j) and can_be_taken(i, j)) { visited.emplace(i, j); Q.emplace_back(i, j); } } int answer = 0; while (!Q.empty()) { auto [i, j] = Q.front(); Q.pop_front(); points.erase(pair(i, j)); ++answer; for (auto [x, y] : get_neis(i, j)) { if (x < 0 or x >= n or y < 0 or y >= m) continue; if (exists(x, y) and !visited.contains({x, y}) and can_be_taken(x, y)) { visited.emplace(x, y); Q.emplace_back(x, y); } } } return answer; } int main() { ios_base::sync_with_stdio(0); cin.tie(0); int k, q; cin >> n >> m >> k >> q; REP (i, k) { int x, y; cin >> x >> y; --x, --y; org_points.emplace(x, y); } cout << solve() << '\n'; while (q--) { int x, y; cin >> x >> y; --x, --y; if (org_points.contains({x, y})) org_points.erase({x, y}); else org_points.emplace(x, y); cout << solve() << '\n'; } } |
English