leoanjos

Rectangles

Mar 1st, 2023
596
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.94 KB | None | 0 0
  1. #include <bits/stdc++.h>
  2.  
  3. using namespace std;
  4.  
  5. #define llong long long int
  6.  
  7. struct SegmentTree {
  8. private:
  9.     struct Node {
  10.         int odd, lazy;
  11.         Node *left, *right;
  12.  
  13.         Node(): odd(0), lazy(0), left(NULL), right(NULL) {}
  14.         Node(int odd, int lazy, Node *left = NULL, Node *right = NULL): odd(odd), lazy(lazy), left(left), right(right) {}
  15.     };
  16.  
  17.     int mn, mx;
  18.     Node *root;
  19.  
  20. public:
  21.     SegmentTree(int mn, int mx) {
  22.         this->mn = mn;
  23.         this->mx = mx;
  24.         root = new Node();
  25.     }
  26.  
  27.     void update(int l, int r, int v) {
  28.         root = update(root, mn, mx, l, r, v);
  29.     }
  30.  
  31.     int query(int l, int r) {
  32.         return query(root, mn, mx, l, r);
  33.     }
  34.  
  35. private:
  36.     Node* update_lazy(Node *node, int l, int r, int v) {
  37.         if (!node) return new Node(abs(v) & 1 ? r - l + 1 : 0, v);
  38.  
  39.         node->lazy += v;
  40.         if (abs(v) & 1)
  41.             node->odd = r - l - node->odd + 1;
  42.  
  43.         return node;
  44.     }
  45.  
  46.     void push_down(Node *node, int l, int r) {
  47.         int m = (l + r) / 2;
  48.         node->left = update_lazy(node->left, l, m, node->lazy);
  49.         node->right = update_lazy(node->right, m + 1, r, node->lazy);
  50.         node->lazy = 0;
  51.     }
  52.  
  53.     Node* update(Node *node, int l, int r, int ul, int ur, int v) {
  54.         if (r < ul || l > ur) return node;
  55.         if (ul <= l && r <= ur) return update_lazy(node, l, r, v);
  56.         if (!node) return new Node(abs(v) & 1 ? r - l + 1 : 0, v);
  57.  
  58.         push_down(node, l, r);
  59.  
  60.         int m = (l + r) / 2;
  61.         node->left = update(node->left, l, m, ul, ur, v);
  62.         node->right = update(node->right, m + 1, r, ul, ur, v);
  63.         node->odd = (node->left ? node->left->odd : 0) + (node->right ? node->right->odd : 0);
  64.         return node;
  65.     }
  66.  
  67.     int query(Node *node, int l, int r, int ql, int qr) {
  68.         if (!node || r < ql || l > qr) return 0;
  69.         if (ql <= l && r <= qr) return node->odd;
  70.  
  71.         push_down(node, l, r);
  72.  
  73.         int m = (l + r) / 2;
  74.         return query(node->left, l, m, ql, qr) + query(node->right, m + 1, r, ql, qr);
  75.     }
  76. };
  77.  
  78. int main() {
  79.     ios_base::sync_with_stdio(false);
  80.     cin.tie(NULL);
  81.  
  82.     int n; cin >> n;
  83.  
  84.     int mn = INT_MAX, mx = INT_MIN;
  85.     vector<tuple<int, int, int, int>> events;
  86.  
  87.     for (int i = 0; i < n; i++) {
  88.         int x1, y1, x2, y2;
  89.         cin >> x1 >> y1 >> x2 >> y2;
  90.  
  91.         if (x1 > x2) swap(x1, x2);
  92.         if (y1 > y2) swap(y1, y2);
  93.  
  94.         mn = min(mn, y1);
  95.         mx = max(mx, y2 - 1);
  96.  
  97.         events.emplace_back(x1, y1, y2, 1);
  98.         events.emplace_back(x2, y1, y2, -1);
  99.     }
  100.  
  101.     sort(events.begin(), events.end());
  102.  
  103.     llong ans = 0LL;
  104.     int last = get<0>(events[0]);
  105.     SegmentTree tree(mn, mx);
  106.  
  107.     for (auto [x, y1, y2, v]: events) {
  108.         int odd = tree.query(mn, mx);
  109.         ans += 1LL * odd * (x - last);
  110.         tree.update(y1, y2 - 1, v);
  111.         last = x;
  112.     }
  113.  
  114.     cout << ans << "\n";
  115. }
Advertisement
Add Comment
Please, Sign In to add comment