#include <bits/stdc++.h>
using namespace std;
struct DSU {
int n;
vector<int> par, sz, mask;
DSU() {}
DSU(int _n) {
n = _n;
par.resize(n);
sz.resize(n);
mask.resize(n);
for (int i = 0; i < n; ++i) {
par[i] = i, sz[i] = 1;
}
}
int getParent(int v) {
if (par[v] != v) {
par[v] = getParent(par[v]);
}
return par[v];
}
void uniteSets(int v, int u) {
// cerr << "v: " << v << ", u: " << u << '\n';
v = getParent(v), u = getParent(u);
if (v == u) { return; }
if (sz[v] < sz[u]) { swap(v, u); }
par[u] = v;
sz[v] += sz[u];
mask[v] |= mask[u];
}
int getComps() {
int comps = 0;
for (int i = 0; i < n; ++i) {
if (getParent(i) == i && mask[i] == 3) {
++comps;
}
}
return comps;
}
~DSU() {}
};
struct SegTree {
int n, N;
DSU dsu;
vector<int> lazy, sum;
vector<set<int>> leafs;
SegTree() {}
SegTree(int _n, int dsusz) {
n = _n, N = 1;
while (N < n) {
N <<= 1;
}
dsu = DSU(dsusz);
lazy.resize(2 * N, -1);
sum.resize(2 * N);
leafs.resize(N);
}
void push(int v) {
if (v < N) {
if (lazy[2 * v] != -1 && sum[2 * v] > 0) {
// cerr << "pushL\n";
// cerr << v << '\n';
dsu.uniteSets(lazy[2 * v], lazy[v]);
}
if (lazy[2 * v + 1] != -1 && sum[2 * v + 1] > 0) {
// cerr << "pushR\n";
// cerr << v << '\n';
dsu.uniteSets(lazy[2 * v + 1], lazy[v]);
}
lazy[2 * v] = lazy[v];
lazy[2 * v + 1] = lazy[v];
} else {
if (!leafs[v - N].empty()) {
// cerr << "pushLeaf\n";
dsu.uniteSets(lazy[v], *leafs[v - N].begin());
}
}
lazy[v] = -1;
}
void unite(int v, int tl, int tr, int l, int r, int i) {
if (lazy[v] != -1) {
push(v);
}
if (tl >= r || tr <= l) {
return;
}
if (l <= tl && tr <= r) {
lazy[v] = i;
push(v);
return;
}
int m = tl + (tr - tl) / 2;
unite(2 * v, tl, m, l, r, i);
unite(2 * v + 1, m, tr, l, r, i);
}
void unite(int l, int r, int i) {
unite(1, 0, N, l, r, i);
}
void change(int v, int tl, int tr, int pos, int i, int flag) {
if (lazy[v] != -1) {
push(v);
}
if (tl >= pos + 1 || tr <= pos) {
return;
}
if (tl + 1 == tr) {
if (flag > 0) {
// insert
if (!leafs[v - N].empty()) {
// cerr << "when change\n";
dsu.uniteSets(*leafs[v - N].begin(), i);
}
leafs[v - N].emplace(i);
} else {
// erase
leafs[v - N].erase(i);
}
sum[v] = !leafs[v - N].empty();
return;
}
int m = tl + (tr - tl) / 2;
change(2 * v, tl, m, pos, i, flag);
change(2 * v + 1, m, tr, pos, i, flag);
sum[v] = sum[2 * v] + sum[2 * v + 1];
}
void change(int pos, int i, int flag) {
change(1, 0, N, pos, i, flag);
}
int getSum(int l, int r) {
if (l > r) { return 0; }
int vl = N + l, vr = N + r, res = 0;
while (vl < vr) {
if (vl & 1) {
res += sum[vl];
}
if ((vr ^ 1) & 1) {
res += sum[vr];
}
vl = (vl + 1) >> 1;
vr = (vr - 1) >> 1;
}
if (vl == vr) {
res += sum[vl];
}
return res;
}
~SegTree() {}
};
struct Event {
int lx, rx, y, type, i;
Event() {}
Event(int _lx, int _rx, int _y, int _type, int _i) {
lx = _lx, rx = _rx, y = _y, type = _type, i = _i;
}
bool operator<(const Event& other) const {
return make_pair(y, type) < make_pair(other.y, other.type);
}
~Event() {}
};
void solve() {
int w, h, n;
cin >> w >> h >> n;
vector<vector<int>> cuts(n + 4, vector<int>(4));
for (int i = 0; i < n; ++i) {
for (int j = 0; j < 4; ++j) {
cin >> cuts[i][j];
}
}
cuts[n] = {0, 0, 0, h};
cuts[n + 1] = {0, h, w, h};
cuts[n + 2] = {w, 0, w, h};
cuts[n + 3] = {0, 0, w, 0};
n += 4;
for (int i = 0; i < n; ++i) {
if (cuts[i][0] == cuts[i][2] && cuts[i][1] == cuts[i][3]) {
swap(cuts[i], cuts.back());
cuts.pop_back();
--i;
--n;
}
}
vector<Event> evs;
vector<int> allX;
auto getX = [&](int x) {
return lower_bound(allX.begin(), allX.end(), x) - allX.begin();
};
auto calc = [&]() -> vector<long long> {
SegTree st(allX.size(), n);
for (int i = 0; i < n; ++i) {
if (cuts[i][0] == cuts[i][2]) {
st.dsu.mask[i] = 1;
} else {
st.dsu.mask[i] = 2;
}
}
set<pair<int, int>> segs;
vector<long long> res = {0, 0, 0};
for (int l = 0; l < (int)evs.size(); ++l) {
if (evs[l].type == 0) {
segs.clear();
int r = l - 1;
while (r + 1 < (int)evs.size() && evs[r + 1].type == 0 && evs[r + 1].y == evs[l].y) {
++r;
st.unite(getX(evs[r].lx), getX(evs[r].rx) + 1, evs[r].i);
int newL = evs[r].lx, newR = evs[r].rx;
auto it = segs.lower_bound(make_pair(evs[r].lx, 0));
while (it != segs.end() && it->second <= evs[r].rx) {
newL = min(newL, it->second);
newR = max(newR, it->first);
it = segs.erase(it);
}
segs.emplace(newR, newL);
}
while (!segs.empty()) {
auto [rx, lx] = *segs.begin();
segs.erase(segs.begin());
int ptrL = getX(lx), ptrR = getX(rx), points;
points = st.getSum(ptrL, ptrR);
// cerr << "y: " << evs[r].y << ", lx: " << lx << ", rx: " << rx << ", points: " << points << '\n';
res[0] += points, res[1] += max(0, points - 1);
}
l = r;
} else {
// cerr << "y: " << evs[l].y << ", x: " << evs[l].lx << ", type: " << evs[l].type << '\n';
st.change(getX(evs[l].lx), evs[l].i, -evs[l].type);
}
}
res[2] = st.dsu.getComps();
cerr << "res: " << res[0] << ' ' << res[1] << ' ' << res[2] << '\n';
return res;
};
vector<long long> res = {-1, 0, -1};
for (int iter = 0; iter < 2; ++iter) {
allX.clear();
evs.clear();
for (int i = 0; i < n; ++i) {
if (cuts[i][0] == cuts[i][2]) {
// vertical
evs.emplace_back(cuts[i][0], cuts[i][0], cuts[i][1], -1, i);
evs.emplace_back(cuts[i][0], cuts[i][0], cuts[i][3], 1, i);
allX.emplace_back(cuts[i][0]);
} else {
// horizontal
evs.emplace_back(cuts[i][0], cuts[i][2], cuts[i][1], 0, i);
allX.emplace_back(cuts[i][0]);
allX.emplace_back(cuts[i][2]);
}
}
sort(allX.begin(), allX.end());
allX.resize(unique(allX.begin(), allX.end()) - allX.begin());
sort(evs.begin(), evs.end());
vector<long long> tmp = calc();
assert(res[0] == -1 || res[0] == tmp[0]);
assert(res[2] == -1 || res[2] == tmp[2]);
res[0] = tmp[0], res[2] = tmp[2];
res[1] += tmp[1];
for (int i = 0; i < n; ++i) {
swap(cuts[i][0], cuts[i][1]);
swap(cuts[i][2], cuts[i][3]);
}
}
cout << res[1] - res[0] + res[2] << '\n';
}
int main() {
ios_base::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
#ifdef LOCAL
freopen("input.txt", "r", stdin);
freopen("output.txt", "w", stdout);
int T = 1;
cin >> T;
while (T--) {
solve();
cerr << "-----------\n";
cout << "-----------\n";
}
#else
int T = 1;
// cin >> T;
while (T--) {
solve();
}
#endif
return 0;
}
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
1 ms |
348 KB |
Output is correct |
2 |
Correct |
1 ms |
348 KB |
Output is correct |
3 |
Correct |
0 ms |
348 KB |
Output is correct |
4 |
Correct |
1 ms |
348 KB |
Output is correct |
5 |
Correct |
1 ms |
348 KB |
Output is correct |
6 |
Correct |
1 ms |
348 KB |
Output is correct |
7 |
Correct |
1 ms |
604 KB |
Output is correct |
8 |
Correct |
3 ms |
604 KB |
Output is correct |
9 |
Correct |
2 ms |
604 KB |
Output is correct |
10 |
Correct |
3 ms |
604 KB |
Output is correct |
11 |
Correct |
3 ms |
604 KB |
Output is correct |
12 |
Correct |
2 ms |
604 KB |
Output is correct |
13 |
Correct |
3 ms |
604 KB |
Output is correct |
14 |
Correct |
2 ms |
604 KB |
Output is correct |
15 |
Correct |
2 ms |
604 KB |
Output is correct |
16 |
Correct |
1 ms |
348 KB |
Output is correct |
17 |
Correct |
1 ms |
452 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
1 ms |
348 KB |
Output is correct |
2 |
Correct |
1 ms |
348 KB |
Output is correct |
3 |
Correct |
0 ms |
348 KB |
Output is correct |
4 |
Correct |
1 ms |
348 KB |
Output is correct |
5 |
Correct |
1 ms |
348 KB |
Output is correct |
6 |
Correct |
1 ms |
348 KB |
Output is correct |
7 |
Correct |
1 ms |
604 KB |
Output is correct |
8 |
Correct |
3 ms |
604 KB |
Output is correct |
9 |
Correct |
2 ms |
604 KB |
Output is correct |
10 |
Correct |
3 ms |
604 KB |
Output is correct |
11 |
Correct |
3 ms |
604 KB |
Output is correct |
12 |
Correct |
2 ms |
604 KB |
Output is correct |
13 |
Correct |
3 ms |
604 KB |
Output is correct |
14 |
Correct |
2 ms |
604 KB |
Output is correct |
15 |
Correct |
2 ms |
604 KB |
Output is correct |
16 |
Correct |
1 ms |
348 KB |
Output is correct |
17 |
Correct |
1 ms |
452 KB |
Output is correct |
18 |
Correct |
1 ms |
348 KB |
Output is correct |
19 |
Correct |
1 ms |
348 KB |
Output is correct |
20 |
Correct |
1 ms |
348 KB |
Output is correct |
21 |
Correct |
3 ms |
604 KB |
Output is correct |
22 |
Correct |
2 ms |
604 KB |
Output is correct |
23 |
Correct |
3 ms |
604 KB |
Output is correct |
24 |
Correct |
3 ms |
604 KB |
Output is correct |
25 |
Correct |
3 ms |
604 KB |
Output is correct |
26 |
Correct |
2 ms |
604 KB |
Output is correct |
27 |
Correct |
3 ms |
604 KB |
Output is correct |
28 |
Correct |
4 ms |
604 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
2 ms |
604 KB |
Output is correct |
2 |
Correct |
2 ms |
472 KB |
Output is correct |
3 |
Correct |
2 ms |
604 KB |
Output is correct |
4 |
Correct |
3 ms |
604 KB |
Output is correct |
5 |
Correct |
28 ms |
3060 KB |
Output is correct |
6 |
Correct |
153 ms |
16404 KB |
Output is correct |
7 |
Correct |
340 ms |
33556 KB |
Output is correct |
8 |
Correct |
332 ms |
33500 KB |
Output is correct |
9 |
Correct |
290 ms |
34272 KB |
Output is correct |
10 |
Correct |
255 ms |
33496 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
1 ms |
348 KB |
Output is correct |
2 |
Correct |
3 ms |
604 KB |
Output is correct |
3 |
Correct |
32 ms |
2708 KB |
Output is correct |
4 |
Correct |
1 ms |
348 KB |
Output is correct |
5 |
Correct |
3 ms |
604 KB |
Output is correct |
6 |
Correct |
515 ms |
30520 KB |
Output is correct |
7 |
Correct |
14 ms |
2232 KB |
Output is correct |
8 |
Correct |
171 ms |
18004 KB |
Output is correct |
9 |
Correct |
203 ms |
17880 KB |
Output is correct |
10 |
Correct |
215 ms |
17112 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
1 ms |
348 KB |
Output is correct |
2 |
Correct |
1 ms |
348 KB |
Output is correct |
3 |
Correct |
0 ms |
348 KB |
Output is correct |
4 |
Correct |
1 ms |
348 KB |
Output is correct |
5 |
Correct |
1 ms |
348 KB |
Output is correct |
6 |
Correct |
1 ms |
348 KB |
Output is correct |
7 |
Correct |
1 ms |
604 KB |
Output is correct |
8 |
Correct |
3 ms |
604 KB |
Output is correct |
9 |
Correct |
2 ms |
604 KB |
Output is correct |
10 |
Correct |
3 ms |
604 KB |
Output is correct |
11 |
Correct |
3 ms |
604 KB |
Output is correct |
12 |
Correct |
2 ms |
604 KB |
Output is correct |
13 |
Correct |
3 ms |
604 KB |
Output is correct |
14 |
Correct |
2 ms |
604 KB |
Output is correct |
15 |
Correct |
2 ms |
604 KB |
Output is correct |
16 |
Correct |
1 ms |
348 KB |
Output is correct |
17 |
Correct |
1 ms |
452 KB |
Output is correct |
18 |
Correct |
1 ms |
348 KB |
Output is correct |
19 |
Correct |
1 ms |
348 KB |
Output is correct |
20 |
Correct |
1 ms |
348 KB |
Output is correct |
21 |
Correct |
3 ms |
604 KB |
Output is correct |
22 |
Correct |
2 ms |
604 KB |
Output is correct |
23 |
Correct |
3 ms |
604 KB |
Output is correct |
24 |
Correct |
3 ms |
604 KB |
Output is correct |
25 |
Correct |
3 ms |
604 KB |
Output is correct |
26 |
Correct |
2 ms |
604 KB |
Output is correct |
27 |
Correct |
3 ms |
604 KB |
Output is correct |
28 |
Correct |
4 ms |
604 KB |
Output is correct |
29 |
Correct |
2 ms |
604 KB |
Output is correct |
30 |
Correct |
2 ms |
472 KB |
Output is correct |
31 |
Correct |
2 ms |
604 KB |
Output is correct |
32 |
Correct |
3 ms |
604 KB |
Output is correct |
33 |
Correct |
28 ms |
3060 KB |
Output is correct |
34 |
Correct |
153 ms |
16404 KB |
Output is correct |
35 |
Correct |
340 ms |
33556 KB |
Output is correct |
36 |
Correct |
332 ms |
33500 KB |
Output is correct |
37 |
Correct |
290 ms |
34272 KB |
Output is correct |
38 |
Correct |
255 ms |
33496 KB |
Output is correct |
39 |
Correct |
1 ms |
348 KB |
Output is correct |
40 |
Correct |
3 ms |
604 KB |
Output is correct |
41 |
Correct |
32 ms |
2708 KB |
Output is correct |
42 |
Correct |
1 ms |
348 KB |
Output is correct |
43 |
Correct |
3 ms |
604 KB |
Output is correct |
44 |
Correct |
515 ms |
30520 KB |
Output is correct |
45 |
Correct |
14 ms |
2232 KB |
Output is correct |
46 |
Correct |
171 ms |
18004 KB |
Output is correct |
47 |
Correct |
203 ms |
17880 KB |
Output is correct |
48 |
Correct |
215 ms |
17112 KB |
Output is correct |
49 |
Correct |
3 ms |
604 KB |
Output is correct |
50 |
Correct |
3 ms |
604 KB |
Output is correct |
51 |
Correct |
3 ms |
604 KB |
Output is correct |
52 |
Correct |
217 ms |
16480 KB |
Output is correct |
53 |
Correct |
151 ms |
16620 KB |
Output is correct |
54 |
Correct |
200 ms |
16864 KB |
Output is correct |
55 |
Correct |
470 ms |
35028 KB |
Output is correct |
56 |
Correct |
334 ms |
33756 KB |
Output is correct |
57 |
Correct |
486 ms |
34780 KB |
Output is correct |
58 |
Correct |
463 ms |
35284 KB |
Output is correct |
59 |
Correct |
210 ms |
20956 KB |
Output is correct |
60 |
Correct |
211 ms |
22112 KB |
Output is correct |
61 |
Correct |
232 ms |
21728 KB |
Output is correct |
62 |
Correct |
260 ms |
22244 KB |
Output is correct |
63 |
Correct |
499 ms |
36548 KB |
Output is correct |
64 |
Correct |
285 ms |
33500 KB |
Output is correct |
65 |
Correct |
497 ms |
34336 KB |
Output is correct |
66 |
Correct |
499 ms |
33744 KB |
Output is correct |
67 |
Correct |
434 ms |
34004 KB |
Output is correct |
68 |
Correct |
401 ms |
33168 KB |
Output is correct |
69 |
Correct |
434 ms |
33380 KB |
Output is correct |
70 |
Correct |
436 ms |
33016 KB |
Output is correct |
71 |
Correct |
240 ms |
24800 KB |
Output is correct |
72 |
Correct |
242 ms |
24968 KB |
Output is correct |