Rectangles(2018-2019 ACM-ICPC Pacific Northwest Regional Contest (Div. 1))扫描线+线段树

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

求 n 个矩形中奇数个矩形覆盖区域的面积和   

#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;
}

猜你喜欢

转载自www.cnblogs.com/xxxsans/p/12801446.html