1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134
| auto optimize_cpp_stdio = []() { std::ios::sync_with_stdio(false); std::cin.tie(nullptr); std::cout.tie(nullptr); return 0; }(); struct Line { int x, y1, y2, flag; bool operator<(const Line &p) const { return x == p.x ? flag < p.flag : x < p.x; } };
struct SegTree { struct TreeNode { int l, r; int lazy, sum; }; vector<TreeNode> tree; vector<int> &yy; SegTree(int n, vector<int> &_yy) : tree(n << 2), yy(_yy) { } void build(int cur, int l, int r) { tree[cur].l = l, tree[cur].r = r; tree[cur].lazy = 0, tree[cur].sum = 0; if (l == r) return; int mid = (l + r) >> 1; build(cur << 1, l, mid); build(cur << 1 | 1, mid + 1, r); } void update(int cur, int l, int r, int k) { if (l <= tree[cur].l && tree[cur].r <= r) { tree[cur].lazy += k; tree[cur].sum += k * (tree[cur].r + 1 - tree[cur].l); return; } int mid = (tree[cur].l + tree[cur].r) >> 1; if (tree[cur].lazy) pushdown(cur); if (l <= mid) update(cur << 1, l, r, k); if (mid + 1 <= r) update(cur << 1 | 1, l, r, k); tree[cur].sum = tree[cur << 1].sum + tree[cur << 1 | 1].sum; } int query(int cur, int l, int r) { if (l <= tree[cur].l && tree[cur].r <= r) { return tree[cur].sum; } if (tree[cur].lazy) pushdown(cur); int sum = 0; int mid = (tree[cur].l + tree[cur].r) >> 1; if (l <= mid) sum += query(cur << 1, l, r); if (mid + 1 <= r) sum += query(cur << 1 | 1, l, r); return sum; } void pushdown(int cur) { tree[cur << 1].lazy += tree[cur].lazy; tree[cur << 1].sum += tree[cur].lazy * (tree[cur << 1].r + 1 - tree[cur << 1].l); tree[cur << 1 | 1].lazy += tree[cur].lazy; tree[cur << 1 | 1].sum += tree[cur].lazy * (tree[cur << 1 | 1].r + 1 - tree[cur << 1 | 1].l); tree[cur].lazy = 0; } };
class Solution { public: const static int maxn = 1e5 + 10; const static int maxm = 1e5 + 10; const int INF = 0x3f3f3f3f; vector<Line> line; vector<int> yy; bool isRectangleCover(vector<vector<int>> &rectangles) { int n = rectangles.size(); line.resize(n * 2); yy.resize(n * 2); long long area = 0; int minx1 = INF, miny1 = INF, maxx2 = -INF, maxy2 = -INF; for (int i = 0; i < n; ++i) { auto &rect = rectangles[i]; int x1 = rect[0], y1 = rect[1], x2 = rect[2], y2 = rect[3]; line[i * 2] = {x1, y1, y2, 1}; line[i * 2 + 1] = {x2, y1, y2, -1}; yy[i * 2] = y1; yy[i * 2 + 1] = y2; area += (x2 - x1) * 1ll * (y2 - y1); minx1 = min(minx1, x1); miny1 = min(miny1, y1); maxx2 = max(maxx2, x2); maxy2 = max(maxy2, y2); } long long area_rect = (maxx2 - minx1) * 1ll * (maxy2 - miny1); if (area != area_rect) return false; yy.emplace_back(-INF); sort(yy.begin(), yy.end()); int tot = unique(yy.begin(), yy.end()) - yy.begin() - 1; sort(line.begin(), line.end()); SegTree segTree(tot, yy); segTree.build(1, 1, tot - 1); long long area_union = 0; for (int i = 0; i < n * 2 - 1; ++i) { int y1 = lower_bound(yy.begin() + 1, yy.begin() + tot + 1, line[i].y1) - yy.begin(); int y2 = lower_bound(yy.begin() + 1, yy.begin() + tot + 1, line[i].y2) - yy.begin(); if (line[i].flag == 1) { if (segTree.query(1, y1, y2 - 1) != 0) return false; } segTree.update(1, y1, y2 - 1, line[i].flag); } return true; } };
|