cheater2k

Drawing Rectangles - University Codesprint 4

Jun 18th, 2018
235
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.17 KB | None | 0 0
  1. #include <bits/stdc++.h>
  2. using namespace std;
  3.  
  4. const int N = 3e5 + 10;
  5.  
  6. struct Query {
  7.     int type; int x; int l; int r;
  8.     bool operator < (const Query &other) const {
  9.         return x < other.x || (x == other.x && type < other.type);
  10.     }
  11. };
  12. vector<Query> sweep;
  13. vector<int> vals;
  14.  
  15. struct SegmentTree {
  16.     int T[N << 2], lz[N << 2];
  17.  
  18.     void reset() {
  19.         memset(T, 0, sizeof T);
  20.         memset(lz, 0, sizeof lz);
  21.     }
  22.     #define mid ((l + r) >> 1)
  23.     void push(int v, int l, int r) {
  24.         if (!lz[v]) return;
  25.         if (l < r) lz[v << 1] += lz[v], lz[v << 1 | 1] += lz[v];
  26.         T[v] += lz[v] * (r - l + 1);
  27.         lz[v] = 0;
  28.     }
  29.     void upd(int v, int l, int r, int L, int R, int val) {
  30.         push(v, l, r);
  31.         if (R < l || L > r) return;
  32.         if (L <= l && r <= R) { lz[v] = val; push(v, l, r); return; }
  33.         upd(v << 1, l, mid, L, R, val);
  34.         upd(v << 1 | 1, mid + 1, r, L, R, val);
  35.         T[v] = T[v << 1] + T[v << 1 | 1];
  36.     }
  37.     void dfs(int v, int l, int r) {
  38.         if (l == r) {
  39.             vals.push_back(l); return;
  40.         }
  41.         push(v << 1, l, mid); push(v << 1 | 1, mid + 1, r);
  42.         if (T[v << 1] > 0) dfs(v << 1, l, mid);
  43.         if (T[v << 1 | 1] > 0) dfs(v << 1 | 1, mid + 1, r);
  44.     }
  45.     #undef mid
  46. } seg;
  47.  
  48. int n;
  49. vector<int> g[N];
  50. bool checkL[N], checkR[N];
  51. int matchL[N], matchR[N];
  52.  
  53. bool dfs(int u) {
  54.     if (u == -1) return true;
  55.     for (int &v : g[u]) {
  56.         if (checkR[v]) continue;
  57.         checkR[v] = true;
  58.         if (dfs(matchR[v])) {
  59.             matchL[u] = v; matchR[v] = u; return true;
  60.         }
  61.     }
  62.     return false;
  63. }
  64.  
  65. void trace(int u) {
  66.     if (checkL[u]) return;
  67.     checkL[u] = true;
  68.     for (int &v : g[u]) {
  69.         if (checkR[v]) continue;
  70.         checkR[v] = true;
  71.         trace(matchR[v]);
  72.     }
  73. }
  74.  
  75. int main() {
  76.     ios_base::sync_with_stdio(false); cin.tie(0);
  77.     cin >> n;
  78.     for (int i = 1; i <= n; ++i) {
  79.         int x1, y1, x2, y2;
  80.         cin >> x1 >> y1 >> x2 >> y2;
  81.         sweep.push_back({+1, x1, y1, y2});
  82.         sweep.push_back({-1, x2 + 1, y1, y2});
  83.     }
  84.     sort(sweep.begin(), sweep.end());
  85.  
  86.     int lstX = 0;
  87.     for (int i = 0; i < sweep.size(); ) {
  88.         int curX = sweep[i].x;
  89.         // lstX -> curX - 1
  90.         vals.clear();
  91.         seg.dfs(1, 0, 3e5);
  92.         for (int &y : vals) {
  93.             for (int x = lstX; x <= curX - 1; ++x) {
  94.                 // add edge (x -> y)
  95.                 g[x].push_back(y);
  96.             }
  97.         }
  98.         while(i < sweep.size() && sweep[i].x == curX) {
  99.             seg.upd(1, 0, 3e5, sweep[i].l, sweep[i].r, sweep[i].type);
  100.             ++i;
  101.         }
  102.         lstX = curX;
  103.     }  
  104.    
  105.     memset(matchL, -1, sizeof matchL);
  106.     memset(matchR, -1, sizeof matchR);
  107.     int rem = 3e5, prev_rem = 3e5 + 1;
  108.     while(rem && rem < prev_rem) {
  109.         prev_rem = rem;
  110.         memset(checkR, 0, sizeof checkR);
  111.         for (int row = 0; row <= 3e5; ++row) {
  112.             if (matchL[row] == -1) {
  113.                 rem -= dfs(row);
  114.             }
  115.         }
  116.     }
  117.  
  118.     int maxmatching = 0;
  119.     memset(checkR, 0, sizeof checkR);
  120.     for (int row = 0; row <= 3e5; ++row) {
  121.         maxmatching += matchL[row] != -1;
  122.         if (matchL[row] == -1) {
  123.             trace(row);
  124.         }
  125.     }
  126.  
  127.     printf("%d\n", maxmatching);
  128.     vector<int> vrow, vcol;
  129.     for (int row = 0; row <= 3e5; ++row) if (!checkL[row]) vrow.push_back(row);
  130.     for (int col = 0; col <= 3e5; ++col) if (checkR[col]) vcol.push_back(col);
  131.     printf("%d\n", vrow.size());
  132.     for (int &row : vrow) printf("%d ", row); printf("\n");
  133.     printf("%d\n", vcol.size());
  134.     for (int &col : vcol) printf("%d ", col); printf("\n");
  135. }
Advertisement
Add Comment
Please, Sign In to add comment