Untitled

 avatar
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