Rectangles(2018-2019 ACM-ICPC Pacific Northwest Regional Contest (Div. 1))扫描线+线段树
求 n 个矩形中奇数个矩形覆盖区域的面积和。
n 个矩形中奇数个矩形覆盖区域的面积和。
You are given several axis-aligned rectangles. Compute the sum of the area of the regions that are covered by an odd number of rectangles.
Input
The first line of input contains a single integer n (1 ≤ n ≤ 105 ), representing the number of rectangles. Each of the next n lines contains four space-separated integers x1, y1, x2, and y2, each between 0 and 109 , describing the coordinates of a rectangle.
Output
Print, on one line, the total area covered by an odd number of rectangles as an exact integer.
Sample Input and Output
2 0 0 4 4 1 1 3 3 12
4 0 0 10 10 1 1 11 11 2 2 12 12 3 3 13 13 72
#include <bits/stdc++.h> using namespace std; typedef long long ll; const int inf = 0x3f3f3f3f; const int mod = 1e9; const int mx = 1e7; //check the limits, dummy typedef pair<int, int> pa; const double PI = acos(-1); ll gcd(ll a, ll b) { return b ? gcd(b, a % b) : a; } #define swa(a,b) a^=b^=a^=b #define re(i,a,b) for(int i=(a),_=(b);i<_;i++) #define rb(i,a,b) for(int i=(a),_=(b);i>=_;i--) #define clr(a) memset(a, inf, sizeof(a)) #define lowbit(x) ((x)&(x-1)) #define mkp make_pai void sc(int& x) { scanf("%d", &x); }void sc(int64_t& x) { scanf("%lld", &x); }void sc(double& x) { scanf("%lf", &x); }void sc(char& x) { scanf(" %c", &x); }void sc(char* x) { scanf("%s", x); } vector<int> x; int Get(int k) { return lower_bound(x.begin(), x.end(), k) - x.begin(); } class seg_tree { public: struct node { int v, lazy; node(int _v = 0, int _lazy = 0): v(_v), lazy(_lazy) {} }; node Unite(const node &k1, const node &k2) { node ans; ans.v = k1.v + k2.v; return ans; } void Pull(int o) { tree[o] = Unite(tree[o << 1], tree[o << 1 | 1]); } void Push(int o, int l, int r) { int m = (l + r) >> 1; if (tree[o].lazy != 0) { tree[o << 1].v = x[m] - x[l - 1] - tree[o << 1].v; tree[o << 1 | 1].v = x[r] - x[m] - tree[o << 1 | 1].v; tree[o << 1].lazy ^= 1; tree[o << 1 | 1].lazy ^= 1; tree[o].lazy = 0; } } int n; vector<node> tree; void Build(int o, int l, int r) { if (l == r) return; int m = (l + r) >> 1; Build(o << 1, l, m); Build(o << 1 | 1, m + 1, r); Pull(o); } seg_tree(int _n): n(_n) { tree.resize(n << 2); Build(1, 1, n); } void Modify(int o, int l, int r, int ll, int rr) { if (ll <= l && rr >= r) { tree[o].v = x[r] - x[l - 1] - tree[o].v; tree[o].lazy ^= 1; return; } Push(o, l, r); int m = (l + r) >> 1; if (ll <= m) Modify(o << 1, l, m, ll, rr); if (rr > m) Modify(o << 1 | 1, m + 1, r, ll, rr); Pull(o); } void Modify(int ll, int rr) { Modify(1, 1, n, ll, rr); } node Query(int o, int l, int r, int ll, int rr) { if (ll <= l && rr >= r) return tree[o]; Push(o, l, r); int m = (l + r) >> 1; node ans; if (ll <= m) ans = Unite(ans, Query(o << 1, l, m, ll, rr)); if (rr > m) ans = Unite(ans, Query(o << 1 | 1, m + 1, r, ll, rr)); Pull(o); return ans; } node Query() { return Query(1, 1, n, 1, n); } }; struct seg {int l, r, h, flag;}; bool operator < (seg k1, seg k2) {return k1.h < k2.h;} vector<seg> s; int main() { ios::sync_with_stdio(false); cin.tie(0); int n; cin >> n; for (int i = 0, x1, y1, x2, y2; i < n; ++i) { cin >> x1 >> y1 >> x2 >> y2; if (x1 > x2) swap(x1, x2); if (y1 > y2) swap(y1, y2); x.emplace_back(x1); x.emplace_back(x2); s.emplace_back((seg){x1, x2, y1, 1}); s.emplace_back((seg){x1, x2, y2, -1}); } sort(s.begin(), s.end()); sort(x.begin(), x.end()); x.erase(unique(x.begin(), x.end()), x.end()); seg_tree sgt(x.size()); ll ans = 0; for (int i = 0, l, r; i < s.size() - 1; ++i) { l = Get(s[i].l), r = Get(s[i].r); sgt.Modify(l + 1, r); ans += (ll)sgt.Query().v * (s[i + 1].h - s[i].h); } cout << ans << endl; return 0; }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步