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
| // 더 많은 정보는 42jerrykim.github.io 에서 확인하세요.
#include <bits/stdc++.h>
using namespace std;
struct Event {
long long x;
int y1_idx, y2_idx;
int delta; // +1 add, -1 remove
bool operator<(const Event& o) const { return x < o.x; }
};
struct SegmentTree {
int n; // number of elementary intervals = ys.size() - 1
const vector<long long>& ys;
vector<int> cover;
vector<long long> covered;
SegmentTree(const vector<long long>& ys_) : ys(ys_) {
n = (int)ys.size() - 1;
cover.assign(n * 4, 0);
covered.assign(n * 4, 0);
}
void pull(int node, int l, int r) {
if (cover[node] > 0) {
covered[node] = ys[r] - ys[l];
} else {
if (l + 1 == r) covered[node] = 0;
else covered[node] = covered[node << 1] + covered[node << 1 | 1];
}
}
void update(int node, int l, int r, int ql, int qr, int val) {
if (qr <= l || r <= ql) return;
if (ql <= l && r <= qr) {
cover[node] += val;
pull(node, l, r);
return;
}
int mid = (l + r) >> 1;
update(node << 1, l, mid, ql, qr, val);
update(node << 1 | 1, mid, r, ql, qr, val);
pull(node, l, r);
}
void update(int l, int r, int val) { // [l, r)
if (l >= r) return;
update(1, 0, n, l, r, val);
}
long long totalCovered() const { return covered[1]; }
};
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int N;
if (!(cin >> N)) return 0;
vector<long long> x1(N), x2(N), y1(N), y2(N);
vector<long long> ys; ys.reserve(2 * N);
for (int i = 0; i < N; ++i) {
cin >> x1[i] >> x2[i] >> y1[i] >> y2[i];
ys.push_back(y1[i]);
ys.push_back(y2[i]);
}
sort(ys.begin(), ys.end());
ys.erase(unique(ys.begin(), ys.end()), ys.end());
vector<Event> ev; ev.reserve(2 * N);
for (int i = 0; i < N; ++i) {
int y1i = (int)(lower_bound(ys.begin(), ys.end(), y1[i]) - ys.begin());
int y2i = (int)(lower_bound(ys.begin(), ys.end(), y2[i]) - ys.begin());
ev.push_back({x1[i], y1i, y2i, +1});
ev.push_back({x2[i], y1i, y2i, -1});
}
sort(ev.begin(), ev.end());
SegmentTree seg(ys);
long long area = 0;
long long prevX = ev.empty() ? 0 : ev[0].x;
size_t i = 0, M = ev.size();
while (i < M) {
long long curX = ev[i].x;
long long dx = curX - prevX;
if (dx != 0) {
area += dx * seg.totalCovered();
prevX = curX;
}
while (i < M && ev[i].x == curX) {
seg.update(ev[i].y1_idx, ev[i].y2_idx, ev[i].delta);
++i;
}
}
cout << area << '\n';
return 0;
}
|