#define _CRT_SECURE_NO_WARNINGS
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <vector>
#include <array>
using namespace std;
/*
http://oj.daimayuan.top/course/15/problem/688
平面上有n个矩形[Xi,1,Xi,2]×[Yi,1,Yi,2]
,也就是左下角(Xi,1,Yi,1)右上角(Xi,2,Yi,2)的矩形。问面积的并是多少。
输入格式
第一行一个整数n(1≤n≤2×105)。
接下来n行,每行四个整数X1,X2,Y1,Y2(1≤X1≤X2≤109,1≤Y1≤Y2≤109)。
注意:可能会有空矩形。
输出格式
输出一个数表示答案。
样例输入
2
1 4 2 3
2 3 1 4
样例输出
5
*/
const int N = 200010;
struct NODE {
int l, r;
//int minv, mincnt;
int lazy;
int mincnt, len;
}tr[N*4];
vector<int> ys;
vector<array<int, 4>> seg;
int n, m;
void update(int u) {
tr[u].mincnt = min(tr[u << 1].mincnt, tr[u << 1 | 1].mincnt);
if (tr[u << 1].mincnt == tr[u << 1 | 1].mincnt) {
tr[u].len = tr[u << 1].len + tr[u << 1 | 1].len;
}
else if (tr[u << 1].mincnt < tr[u << 1 | 1].mincnt) {
tr[u].len = tr[u << 1].len;
}
else {
tr[u].len = tr[u << 1|1].len;
}
}
void build(int u, int l, int r) {
tr[u] = { l, r, 0, 0, 0 };
if (l == r) {
tr[u] = { l, r, 0, 0, ys[l + 1] - ys[l] };
}
else {
int mid = l + r >> 1;
build(u << 1, l, mid);
build(u << 1 | 1, mid + 1, r);
update(u);
}
}
void pushdown(int u) {
int k = tr[u].lazy;
if (tr[u].lazy) {
tr[u<<1].mincnt = tr[u<<1].mincnt + k;
tr[u<<1].lazy = tr[u<<1].lazy + k;
tr[u << 1|1].mincnt = tr[u << 1|1].mincnt + k;
tr[u << 1|1].lazy = tr[u << 1|1].lazy + k;
tr[u].lazy = 0;
}
}
void modify(int u, int l, int r, int k) {
if (l <= tr[u].l && r >= tr[u].r) {
tr[u].mincnt = tr[u].mincnt + k;
tr[u].lazy = tr[u].lazy + k;
}
else {
int mid = tr[u].l + tr[u].r >> 1;
pushdown(u);
if (l <= mid) modify(u << 1, l, r, k);
if (r > mid) modify(u << 1 | 1, l, r, k);
update(u);
}
}
int main() {
scanf("%d",&n);
int idx = 1;
ys.push_back(-1);
seg.push_back({ -1,-1,-1,-1 });
for (int i = 1; i <= n; i++) {
int x1, y1, x2, y2;
scanf("%d%d%d%d", &x1, &x2, &x2, &y2);
ys.push_back(y1); ys.push_back(y2);
seg.push_back({ x1,1,y1,y2 });
seg.push_back({ x2,-1,y1,y2 });
}
sort(ys.begin(), ys.end());
sort(seg.begin(), seg.begin());
ys.erase(unique(ys.begin(), ys.end()), ys.end());
m = ys.size() - 2;
build(1, 1, m);
long long ans = 0;
int totalLen = tr[1].len;
int prex = 0;
for (int i = 1; i < seg.size(); i++) {
int cov = totalLen;
if (tr[1].mincnt == 0) {
cov = totalLen - tr[1].len;
}
ans += 1ll * (seg[i][0] - prex) * cov;
prex = seg[i][0];
int y1 = lower_bound(ys.begin(), ys.end(), seg[i][2]) - ys.begin() ;
int y2 = lower_bound(ys.begin(), ys.end(), seg[i][3]) - ys.begin() ;
modify(1, y1, y2, seg[i][1]);
}
printf("%lld\n", ans);
return 0;
}
标签:Yi,矩形,mincnt,int,daimayuan,面积,tr,Xi,include
From: https://www.cnblogs.com/itdef/p/18243981