矩形面积并
矩形面积并
扫描线,线段树
http://oj.daimayuan.top/course/15/problem/688
#include <iostream>
#include <algorithm>
#include <cstring>
#include <vector>
#include <cmath>
#include <array>
using namespace std;
#define endl "\n"
typedef long long ll;
typedef pair<int, int> PII;
const int N = 2e5 + 10;
int n, m;
vector<int> vx;
vector<array<int, 4> > event;
struct info
{
int minv, mincnt;
};
info operator + (const info &l, const info &r)
{
info t;
t.minv = min(l.minv, r.minv);
if (l.minv == r.minv)
t.mincnt = l.mincnt + r.mincnt;
else if (l.minv < r.minv)
t.mincnt = l.mincnt;
else
t.mincnt = r.mincnt;
return t;
}
struct Node
{
int t;
info val;
}seg[N * 8];
void pushup(int u)
{
seg[u].val = seg[u << 1].val + seg[u << 1 | 1].val;
}
void settag(int u, int t)
{
seg[u].val.minv += t;
seg[u].t += t;
}
void pushdown(int u)
{
if (seg[u].t)
{
settag(u << 1, seg[u].t);
settag(u << 1 | 1, seg[u].t);
seg[u].t = 0;
}
}
void build(int u, int l, int r)
{
if (l == r)
{
//以段而不是点建线段树
seg[u].val = {0, vx[r] - vx[r-1]};
return;
}
int mid = l + r >> 1;
build(u << 1, l, mid);
build(u << 1 | 1, mid + 1, r);
pushup(u);
}
void modify(int u, int l, int r, int ql, int qr, int k)
{
if (l == ql && r == qr)
{
settag(u, k);
return;
}
int mid = l + r >> 1;
pushdown(u);
if (qr <= mid)
modify(u << 1, l, mid, ql, qr, k);
else if (ql > mid)
modify(u << 1 | 1, mid + 1, r, ql, qr, k);
else
{
modify(u << 1, l, mid, ql, mid, k);
modify(u << 1 | 1, mid + 1, r, mid + 1, qr, k);
}
pushup(u);
}
int main()
{
scanf("%d", &n);
for (int i = 1; i <= n; i++)
{
int x1, x2, y1, y2;
scanf("%d%d%d%d", &x1, &x2, &y1, &y2);
vx.push_back(x1);
vx.push_back(x2);
event.push_back({y1, 1, x1, x2});
event.push_back({y2, -1, x1, x2});
}
sort(event.begin(), event.end());
sort(vx.begin(), vx.end());
vx.erase(unique(vx.begin(), vx.end()), vx.end());
m = vx.size() - 1;
build(1, 1, m);
int totlen = seg[1].val.mincnt;
int prey = 0;
ll ans = 0;
for (auto evt : event)
{
int cov = totlen;
if (seg[1].val.minv == 0)
cov = totlen - seg[1].val.mincnt;
ans += (ll)(evt[0] - prey) * cov;
prey = evt[0];
int x1 = lower_bound(vx.begin(), vx.end(), evt[2]) - vx.begin() + 1;
int x2 = lower_bound(vx.begin(), vx.end(), evt[3]) - vx.begin();
if (x1 > x2)
continue;
modify(1, 1, m, x1, x2, evt[1]);
}
printf("%lld\n", ans);
return 0;
}