#include<iostream>
#include<iomanip>
#include<vector>
#include<map>
#include<algorithm>
#define REP(i,n) for(int i=0;i<(n);++i)
#define FOR(i,a,b) for(int i=(a);i<=(b);++i)
using namespace std;
typedef long long int llint;
const int MAX_N = 200000, MAX_V=150000;
int xx[1+MAX_V], yy[1+MAX_V], qx[1+MAX_V], qy[1+MAX_V];
int vn[1+MAX_V], vs[1+MAX_V], ve[1+MAX_V], vw[1+MAX_V];
map<pair<int,int>, int> vmap;
int n, m, k, q, num_z;
int z[1+MAX_V];
void sprawdz(int i) {
//cout << "SPRAWDZ i=" << i << " x="<<xx[i] << " y="<<yy[i] << " z=" << z[i] << endl;
if (z[i]) return;
if (z[vn[i]] && z[vs[i]]) {
//cout << "SPRAWDZ i=" << i << " z:=1 (NS)" << endl;
z[i] = 1;
num_z++;
sprawdz(ve[i]);
sprawdz(vw[i]);
} else if (z[ve[i]] && z[vw[i]]) {
//cout << "SPRAWDZ i=" << i << " z:=1 (EW)" << endl;
z[i] = 1;
num_z++;
sprawdz(vn[i]);
sprawdz(vs[i]);
}
}
void blokuj_somsiadow(int i);
vector<int> blocked;
inline void blokuj_somsiada(int j) {
//cout << "BLOKUJ j="<<j<< " z="<<z[j]<<endl;
if (z[j]) {
z[j] = 0;
num_z--;
blocked.push_back(j);
blokuj_somsiadow(j);
}
}
void blokuj_somsiadow(int i) {
//cout << "SASIAD i="<<i << endl;
if (vn[i]) blokuj_somsiada(vn[i]);
if (vs[i]) blokuj_somsiada(vs[i]);
if (ve[i]) blokuj_somsiada(ve[i]);
if (vw[i]) blokuj_somsiada(vw[i]);
}
void sprawdz_somsiadow(int i) {
blocked.clear();
blokuj_somsiadow(i);
int mbs = blocked.size();
REP(ix, mbs) sprawdz(blocked[ix]);
sprawdz(i);
}
void update_compass(int i) {
int x = xx[i], y = yy[i];
auto it = vmap.find(make_pair(x+1, y));
if (it != vmap.end() && it->second ) { ve[i] = it->second; vw[ve[i]] = i; } else { ve[i] = 0; }
it = vmap.find(make_pair(x-1, y));
if (it != vmap.end() && it->second) { vw[i] = it->second; ve[vw[i]] = i; } else { vw[i] = 0; }
it = vmap.find(make_pair(x, y+1));
if (it != vmap.end() && it->second) { vs[i] = it->second; vn[vs[i]] = i; } else { vs[i] = 0; }
it = vmap.find(make_pair(x, y-1));
if (it != vmap.end() && it->second) { vn[i] = it->second; vs[vn[i]] = i; } else { vn[i] = 0; }
}
int main(void) {
ios_base::sync_with_stdio(false);
cin.tie(NULL);
cin >> n >> m >> k >> q;
FOR(i, 1, k) cin >> xx[i] >> yy[i];
FOR(j, 1, q) cin >> qx[j] >> qy[j];
FOR(i, 1, k) vmap[make_pair(xx[i], yy[i])] = i;
FOR(i, 0, k) vn[i]=vs[i]=ve[i]=vw[i]=0;
FOR(i, 1, k) update_compass(i);
{
FOR(i, 1, k) z[i] = 0;
z[0] = 1;
FOR(i, 1, k) sprawdz(i);
cout << num_z << endl;
}
FOR(j, 1, q) {
auto it = vmap.find(make_pair(qx[j], qy[j]));
if (it == vmap.end() || !it->second) {
k++; xx[k] = qx[j]; yy[k] = qy[j];
//cout << "INSERT k=" <<k << " x=" << xx[k] << " y=" << yy[k] << endl;
vmap[make_pair(xx[k], yy[k])] = k;
update_compass(k);
// cout << "KLOCEK #" << k <<" (" << xx[k] << ","<< yy[k] << ") N:"
// << vn[k] << " E:" << ve[k] << " S:" << vs[k] << " W:" << vw[k] << endl;
z[k] = 0;
sprawdz_somsiadow(k);
} else {
int i = it->second;
if (z[i]) {
//cout << "REMOVE z:=0 i=" << i << endl;
z[i] = 0;
num_z--;
}
if (i < k) {
//cout << "REMOVE i=" <<i << " k=" << k << " x=" << xx[i] << " y=" << yy[i] << endl;
vmap[make_pair(xx[i], yy[i])] = 0;
vmap[make_pair(xx[k], yy[k])] = i;
z[i] = z[k];
int ix_ve = ve[i], ix_vw = vw[i], ix_vn = vn[i], ix_vs = vs[i];
vw[ve[i]] = ve[vw[i]] = vn[vs[i]] = vs[vn[i]] = 0;
if (ve[k]) vw[ve[k]] = i;
if (vw[k]) ve[vw[k]] = i;
if (vs[k]) vn[vs[k]] = i;
if (vn[k]) vs[vn[k]] = i;
xx[i] = xx[k]; yy[i] = yy[k]; k--;
update_compass(i);
sprawdz(ix_ve == k+1 ? i : ix_ve);
sprawdz(ix_vw == k+1 ? i : ix_vw);
sprawdz(ix_vn == k+1 ? i : ix_vn);
sprawdz(ix_vs == k+1 ? i : ix_vs);
} else {
//cout << "ERASE i=" <<i << " x=" << xx[i] << " y=" << yy[i] << endl;
vmap.erase(it);
int ix_ve = ve[i], ix_vw = vw[i], ix_vn = vn[i], ix_vs = vs[i];
vw[ve[i]] = ve[vw[i]] = vn[vs[i]] = vs[vn[i]] = 0;
k--;
sprawdz(ix_ve);
sprawdz(ix_vw);
sprawdz(ix_vn);
sprawdz(ix_vs);
}
}
cout << num_z << endl;
}
return 0;
}
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 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 | #include<iostream> #include<iomanip> #include<vector> #include<map> #include<algorithm> #define REP(i,n) for(int i=0;i<(n);++i) #define FOR(i,a,b) for(int i=(a);i<=(b);++i) using namespace std; typedef long long int llint; const int MAX_N = 200000, MAX_V=150000; int xx[1+MAX_V], yy[1+MAX_V], qx[1+MAX_V], qy[1+MAX_V]; int vn[1+MAX_V], vs[1+MAX_V], ve[1+MAX_V], vw[1+MAX_V]; map<pair<int,int>, int> vmap; int n, m, k, q, num_z; int z[1+MAX_V]; void sprawdz(int i) { //cout << "SPRAWDZ i=" << i << " x="<<xx[i] << " y="<<yy[i] << " z=" << z[i] << endl; if (z[i]) return; if (z[vn[i]] && z[vs[i]]) { //cout << "SPRAWDZ i=" << i << " z:=1 (NS)" << endl; z[i] = 1; num_z++; sprawdz(ve[i]); sprawdz(vw[i]); } else if (z[ve[i]] && z[vw[i]]) { //cout << "SPRAWDZ i=" << i << " z:=1 (EW)" << endl; z[i] = 1; num_z++; sprawdz(vn[i]); sprawdz(vs[i]); } } void blokuj_somsiadow(int i); vector<int> blocked; inline void blokuj_somsiada(int j) { //cout << "BLOKUJ j="<<j<< " z="<<z[j]<<endl; if (z[j]) { z[j] = 0; num_z--; blocked.push_back(j); blokuj_somsiadow(j); } } void blokuj_somsiadow(int i) { //cout << "SASIAD i="<<i << endl; if (vn[i]) blokuj_somsiada(vn[i]); if (vs[i]) blokuj_somsiada(vs[i]); if (ve[i]) blokuj_somsiada(ve[i]); if (vw[i]) blokuj_somsiada(vw[i]); } void sprawdz_somsiadow(int i) { blocked.clear(); blokuj_somsiadow(i); int mbs = blocked.size(); REP(ix, mbs) sprawdz(blocked[ix]); sprawdz(i); } void update_compass(int i) { int x = xx[i], y = yy[i]; auto it = vmap.find(make_pair(x+1, y)); if (it != vmap.end() && it->second ) { ve[i] = it->second; vw[ve[i]] = i; } else { ve[i] = 0; } it = vmap.find(make_pair(x-1, y)); if (it != vmap.end() && it->second) { vw[i] = it->second; ve[vw[i]] = i; } else { vw[i] = 0; } it = vmap.find(make_pair(x, y+1)); if (it != vmap.end() && it->second) { vs[i] = it->second; vn[vs[i]] = i; } else { vs[i] = 0; } it = vmap.find(make_pair(x, y-1)); if (it != vmap.end() && it->second) { vn[i] = it->second; vs[vn[i]] = i; } else { vn[i] = 0; } } int main(void) { ios_base::sync_with_stdio(false); cin.tie(NULL); cin >> n >> m >> k >> q; FOR(i, 1, k) cin >> xx[i] >> yy[i]; FOR(j, 1, q) cin >> qx[j] >> qy[j]; FOR(i, 1, k) vmap[make_pair(xx[i], yy[i])] = i; FOR(i, 0, k) vn[i]=vs[i]=ve[i]=vw[i]=0; FOR(i, 1, k) update_compass(i); { FOR(i, 1, k) z[i] = 0; z[0] = 1; FOR(i, 1, k) sprawdz(i); cout << num_z << endl; } FOR(j, 1, q) { auto it = vmap.find(make_pair(qx[j], qy[j])); if (it == vmap.end() || !it->second) { k++; xx[k] = qx[j]; yy[k] = qy[j]; //cout << "INSERT k=" <<k << " x=" << xx[k] << " y=" << yy[k] << endl; vmap[make_pair(xx[k], yy[k])] = k; update_compass(k); // cout << "KLOCEK #" << k <<" (" << xx[k] << ","<< yy[k] << ") N:" // << vn[k] << " E:" << ve[k] << " S:" << vs[k] << " W:" << vw[k] << endl; z[k] = 0; sprawdz_somsiadow(k); } else { int i = it->second; if (z[i]) { //cout << "REMOVE z:=0 i=" << i << endl; z[i] = 0; num_z--; } if (i < k) { //cout << "REMOVE i=" <<i << " k=" << k << " x=" << xx[i] << " y=" << yy[i] << endl; vmap[make_pair(xx[i], yy[i])] = 0; vmap[make_pair(xx[k], yy[k])] = i; z[i] = z[k]; int ix_ve = ve[i], ix_vw = vw[i], ix_vn = vn[i], ix_vs = vs[i]; vw[ve[i]] = ve[vw[i]] = vn[vs[i]] = vs[vn[i]] = 0; if (ve[k]) vw[ve[k]] = i; if (vw[k]) ve[vw[k]] = i; if (vs[k]) vn[vs[k]] = i; if (vn[k]) vs[vn[k]] = i; xx[i] = xx[k]; yy[i] = yy[k]; k--; update_compass(i); sprawdz(ix_ve == k+1 ? i : ix_ve); sprawdz(ix_vw == k+1 ? i : ix_vw); sprawdz(ix_vn == k+1 ? i : ix_vn); sprawdz(ix_vs == k+1 ? i : ix_vs); } else { //cout << "ERASE i=" <<i << " x=" << xx[i] << " y=" << yy[i] << endl; vmap.erase(it); int ix_ve = ve[i], ix_vw = vw[i], ix_vn = vn[i], ix_vs = vs[i]; vw[ve[i]] = ve[vw[i]] = vn[vs[i]] = vs[vn[i]] = 0; k--; sprawdz(ix_ve); sprawdz(ix_vw); sprawdz(ix_vn); sprawdz(ix_vs); } } cout << num_z << endl; } return 0; } |
English