Untitled
unknown
plain_text
2 years ago
5.6 kB
16
Indexable
#include <iostream>
#include <vector>
#include <algorithm>
#include <map>
#include <functional>
int main() {
int n;
std::cin >> n;
if (n == 0) {
std::cout << 0 << std::endl;
} else {
std::vector<std::vector<int>> CordsSortedOpen;
std::vector<std::vector<int>> CordsSortedClose;
std::vector<int> CordsX;
std::vector<int> CordsY;
for (int i = 0; i < n; ++i) {
std::vector<int> a(4);
for (int j = 0; j < 4; ++j) {
std::cin >> a[j];
}
CordsSortedOpen.push_back(a);
CordsSortedClose.push_back(a);
CordsX.push_back(a[0]);
CordsX.push_back(a[2]);
CordsY.push_back(a[1]);
CordsY.push_back(a[3]);
}
std::sort(CordsSortedOpen.begin(), CordsSortedOpen.end(), [](const std::vector<int>& x, const std::vector<int>& y) { return x[0] < y[0]; });
std::sort(CordsSortedClose.begin(), CordsSortedClose.end(), [](const std::vector<int>& x, const std::vector<int>& y) { return x[2] < y[2]; });
std::sort(CordsX.begin(), CordsX.end());
CordsX.erase(std::unique(CordsX.begin(), CordsX.end()), CordsX.end());
std::sort(CordsY.begin(), CordsY.end());
CordsY.erase(std::unique(CordsY.begin(), CordsY.end()), CordsY.end());
int MAXY = CordsY.back();
int MINY = CordsY.front();
int RASMER_REALLY = MAXY - MINY;
int RASMER = CordsY.size() - 1;
std::vector<std::pair<int, int>> t(4 * RASMER);
std::vector<int> ADD(4 * RASMER);
auto compression = [](const std::pair<int, int>& x, const std::pair<int, int>& y) {
if (x.first == y.first) {
return std::make_pair(x.first, x.second + y.second);
} else if (x.first < y.first) {
return x;
} else {
return y;
}
};
std::function<void(int, int, int)> init = [&](int v, int l, int r) {
t[v] = std::make_pair(0, CordsY[r] - CordsY[l]);
ADD[v] = 0;
};
std::function<void(int, int, int)> build = [&](int v, int l, int r) {
if ((r - l) == 1) {
init(v, l, r);
return;
}
int m = (l + r) / 2;
build(2 * v + 1, l, m);
build(2 * v + 2, m, r);
t[v] = compression(t[2 * v + 1], t[2 * v + 2]);
};
build(0, 0, RASMER);
std::function<void(int)> push = [&](int v) {
if (ADD[v] == 0) {
return;
}
t[2 * v + 1].first = std::max(ADD[v] + t[2 * v + 1].first, 0);
t[2 * v + 2].first = std::max(ADD[v] + t[2 * v + 2].first, 0);
ADD[2 * v + 1] += ADD[v];
ADD[2 * v + 2] += ADD[v];
ADD[v] = 0;
};
std::function<void(int, int, int, int, int, int)> add = [&](int v, int l, int r, int ql, int qr, int x) {
if (qr <= l || ql >= r) {
return;
}
if (ql <= l && r <= qr) {
ADD[v] += x;
t[v].first = std::max(x + t[v].first, 0);
return;
}
int m = (l + r) / 2;
push(v);
add(2 * v + 1, l, m, ql, qr, x);
add(2 * v + 2, m, r, ql, qr, x);
t[v] = compression(t[2 * v + 1], t[2 * v + 2]);
};
std::function<std::pair<int, int>(int, int, int, int, int)> get = [&](int v, int l, int r, int ql, int qr) {
if (ql >= r || qr <= l) {
return std::make_pair(+1000000000, 0);
}
if (ql <= l && qr >= r) {
return t[v];
}
int m = (l + r) / 2;
push(v);
return compression(get(2 * v + 1, l, m, ql, qr), get(2 * v + 2, m, r, ql, qr));
};
std::map<int, int> yIndex;
for (int i = 0; i < CordsY.size(); ++i) {
yIndex[CordsY[i]] = i;
}
int s = 0;
for (int i = 0; i < CordsX.size(); ++i) {
while (!CordsSortedOpen.empty() && CordsSortedOpen.front()[0] == CordsX[i]) {
std::vector<int> x = CordsSortedOpen.front();
if (x[3] == x[1]) {
CordsSortedOpen.erase(CordsSortedOpen.begin());
continue;
}
add(0, 0, RASMER, yIndex[x[1]], yIndex[x[3]], 1);
CordsSortedOpen.erase(CordsSortedOpen.begin());
}
while (!CordsSortedClose.empty() && CordsSortedClose.front()[2] == CordsX[i]) {
std::vector<int> x = CordsSortedClose.front();
if (x[3] == x[1]) {
CordsSortedClose.erase(CordsSortedClose.begin());
continue;
}
add(0, 0, RASMER, yIndex[x[1]], yIndex[x[3]], -1);
CordsSortedClose.erase(CordsSortedClose.begin());
}
std::pair<int, int> y = get(0, 0, RASMER, 0, RASMER);
int promez = 0;
if (i != CordsX.size() - 1) {
promez = CordsX[i + 1] - CordsX[i];
}
if (y.first == 0) {
s += (RASMER_REALLY - y.second) * promez;
} else {
s += RASMER_REALLY * promez;
}
}
std::cout << s << std::endl;
}
return 0;
}
Editor is loading...
Leave a Comment