/* * Opis: Główny nagłówek */ #include<bits/stdc++.h> using namespace std; using LL=long long; #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<<"}";} #define debug(X...)cerr<<"["#X"]: ",[](auto...$){((cerr<<$<<"; "),...)<<endl;}(X) #else #define debug(...){} #endif #define mp make_pair constexpr array<pair<int,int>, 4> moves{mp(1, 0), mp(-1, 0), mp(0, 1), mp(0, -1)}; struct Grid { int n, m; map<pair<int,int>, bool> blocks; int res = 0; Grid(int _n, int _m) : n(_n), m(_m) { } bool is_wall(pair<int,int> wh) { return wh.first <= 0 || wh.first > n || wh.second <= 0 || wh.second > m; } bool is_occupied(pair<int,int> wh) { // if (is_wall(wh)) { // return true; // } return blocks.count(wh) > 0 && blocks[wh]; } bool check(pair<int,int> wh) { if (is_wall(wh)) { return false; } if (blocks.count(wh) == 0) { return false; } if (!blocks[wh]) { return false; } int cnt_n = 0, cnt_m = 0; cnt_n += is_occupied({wh.first-1, wh.second}); cnt_n += is_occupied({wh.first+1, wh.second}); // if (cnt_n == 2) { // return false; // } cnt_m += is_occupied({wh.first, wh.second+1}); cnt_m += is_occupied({wh.first, wh.second-1}); if (cnt_n * cnt_m > 0) { return false; } return true; } void dfs(pair<int, int> wh) { debug("removing", wh); blocks[wh] = false; res++; for (auto [dx, dy] : moves) { pair<int, int> new_wh = {wh.first + dx, wh.second + dy}; if (check(new_wh)) { dfs(new_wh); } } } int solve() { res = 0; for (auto& [k, v] : blocks) { v = true; } for (auto [k, v] : blocks) { if (check(k)) { dfs(k); } } return res; } void remove(pair<int,int> wh) { blocks.erase(wh); } void add(pair<int,int> wh) { blocks[wh] = true; } void update(pair<int,int> wh) { if (blocks.count(wh) > 0) { remove(wh); } else { add(wh); } } }; int main() { cin.tie(0)->sync_with_stdio(0); int n, m, k, q; cin >> n >> m >> k >> q; Grid grid(n, m); REP(i, k) { int x, y; cin >> x >> y; grid.add({x, y}); } cout << grid.solve() << "\n"; REP(i, q) { int x, y; cin >> x >> y; grid.update({x, y}); cout << grid.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 122 123 124 125 126 127 128 129 130 | /* * Opis: Główny nagłówek */ #include<bits/stdc++.h> using namespace std; using LL=long long; #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<<"}";} #define debug(X...)cerr<<"["#X"]: ",[](auto...$){((cerr<<$<<"; "),...)<<endl;}(X) #else #define debug(...){} #endif #define mp make_pair constexpr array<pair<int,int>, 4> moves{mp(1, 0), mp(-1, 0), mp(0, 1), mp(0, -1)}; struct Grid { int n, m; map<pair<int,int>, bool> blocks; int res = 0; Grid(int _n, int _m) : n(_n), m(_m) { } bool is_wall(pair<int,int> wh) { return wh.first <= 0 || wh.first > n || wh.second <= 0 || wh.second > m; } bool is_occupied(pair<int,int> wh) { // if (is_wall(wh)) { // return true; // } return blocks.count(wh) > 0 && blocks[wh]; } bool check(pair<int,int> wh) { if (is_wall(wh)) { return false; } if (blocks.count(wh) == 0) { return false; } if (!blocks[wh]) { return false; } int cnt_n = 0, cnt_m = 0; cnt_n += is_occupied({wh.first-1, wh.second}); cnt_n += is_occupied({wh.first+1, wh.second}); // if (cnt_n == 2) { // return false; // } cnt_m += is_occupied({wh.first, wh.second+1}); cnt_m += is_occupied({wh.first, wh.second-1}); if (cnt_n * cnt_m > 0) { return false; } return true; } void dfs(pair<int, int> wh) { debug("removing", wh); blocks[wh] = false; res++; for (auto [dx, dy] : moves) { pair<int, int> new_wh = {wh.first + dx, wh.second + dy}; if (check(new_wh)) { dfs(new_wh); } } } int solve() { res = 0; for (auto& [k, v] : blocks) { v = true; } for (auto [k, v] : blocks) { if (check(k)) { dfs(k); } } return res; } void remove(pair<int,int> wh) { blocks.erase(wh); } void add(pair<int,int> wh) { blocks[wh] = true; } void update(pair<int,int> wh) { if (blocks.count(wh) > 0) { remove(wh); } else { add(wh); } } }; int main() { cin.tie(0)->sync_with_stdio(0); int n, m, k, q; cin >> n >> m >> k >> q; Grid grid(n, m); REP(i, k) { int x, y; cin >> x >> y; grid.add({x, y}); } cout << grid.solve() << "\n"; REP(i, q) { int x, y; cin >> x >> y; grid.update({x, y}); cout << grid.solve() << "\n"; } } |