Untitled
unknown
plain_text
a year ago
5.6 kB
3
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