传送门:洛谷P1856
墙上贴着许多形状相同的海报、照片。它们的边都是水平和垂直的。每个矩形图片可能部分或全部的覆盖了其他图片。所有矩形合并后的边长称为周长。
矩形的周长并,注意线段的排序:坐标相同是,入边优先
#include
#include
#include
#include
#define IL inline
using namespace std;
IL int read()
{
char c = getchar();
int sum = 0 , k = 1;
for(; '0' > c || c > '9'; c = getchar())
if(c == '-') k = -1;
for(; '0' <= c && c <= '9'; c = getchar()) sum = sum * 10 + c - '0';
return sum * k;
}
struct segment
{
int x, y1, y2, k;
IL segment(int x_ = 0, int y1_ = 0, int y2_ = 0, int k_ = 0)
{
x = x_; y1 = y1_; y2 = y2_; k = k_;
}
friend bool operator < (const segment &a, const segment &b)
{
if(a.x == b.x) return a.k > b.k;
return a.x < b.x;
}
}seg[10005];
struct node
{
node *lch, *rch;
int cnt, len, cov;
bool covl, covr;
IL node()
{
lch = rch = 0;
cnt = len = cov = 0;
covl = covr = 0;
}
} *root;
int n, m;
int num[10005];
IL int abs_(int x) { return x >= 0 ? x : -x; }
IL void build(node *p, int l, int r)
{
if(l == r) return ;
int mid = (l + r) >> 1;
p->lch = new node; build(p->lch, l, mid);
p->rch = new node; build(p->rch, mid + 1, r);
}
IL void pushup(node *p, int l, int r)
{
if(p->cnt > 0)
{
p->covl = p->covr = 1;
p->cov = 1;
p->len = num[r + 1] - num[l];
}else
if(l == r)
{
p->covl = p->covr = 0;
p->cov = 0;
p->len = 0;
}else
{
p->covl = p->lch->covl; p->covr = p->rch->covr;
p->cov = p->lch->cov + p->rch->cov - (p->lch->covr & p->rch->covl);
p->len = p->lch->len + p->rch->len;
}
}
IL void update(node *p, int l, int r, int x, int y, int k)
{
if(l == x && r == y)
{
p->cnt += k;
pushup(p, l ,r);
return ;
}
int mid = (l + r) >> 1;
if(y <= mid) update(p->lch, l, mid, x, y, k); else
if(mid < x) update(p->rch, mid + 1, r, x, y, k); else
{
update(p->lch, l, mid, x, mid, k);
update(p->rch, mid + 1, r , mid + 1, y, k);
}
pushup(p, l, r);
}
int main()
{
n = read();
for(int i = 1, k = 0, x1, y1, x2, y2; i <= n; ++i)
{
x1 = read(); y1 = read(); x2 = read(); y2 = read();
seg[++k] = segment(x1, y1, y2, 1);
seg[++k] = segment(x2, y1, y2, -1);
num[++m] = y1; num[++m] = y2;
}
n <<= 1;
sort(seg + 1,seg + n + 1);
sort(num + 1, num + m + 1);
m = unique(num + 1, num + m + 1) - (num + 1);
root = new node;
build(root, 1, m - 1);
int ans = 0;
++n;
for(int i = 1, pre = 0, y1, y2; i <= n; ++i)
{
ans += (seg[i].x - seg[i - 1].x) * (root->cov) << 1;
ans += abs_(root->len - pre); pre = root->len;
if(i < n)
{
y1 = lower_bound(num + 1, num + m + 1, seg[i].y1) - num;
y2 = lower_bound(num + 1, num + m + 1, seg[i].y2) - num - 1;
update(root, 1, m - 1, y1, y2, seg[i].k);
}
}
printf("%d\n", ans);
return 0;
}