10
solution:
首先将每个矩形用左右两边表示并标记每个线段是左边的边还是右边的边,然后对这些线段按x坐标升序排序,用一根线从左往右扫描这些线段,那么相邻两根扫描线之间围成的矩形面积之和即为面积并,那么我们只需要知道每个扫描线上被线段覆盖的长度,将其乘以相邻两根扫描线之间的距离即为扫描线扫过的面积,因此我们对y轴建一棵线段树(对所有线段的纵坐标离散化后建树),那么每条线段就可以用线段树中的一个区间来表示,每次扫到左边的边就在线段树中覆盖这条边对应的区间,扫到右边的边就在线段树中取消对这条边的覆盖,每扫过一根线段就维护一下扫描线被覆盖的长度即可 首先将每个矩形用左右两边表示并标记每个线段是左边的边还是右边的边,然后对这些线段按x坐标升序排序,用一根线从左往右扫描这些线段,那么相邻两根扫描线之间围成的矩形面积之和即为面积并,那么我们只需要知道每个扫描线上被线段覆盖的长度,将其乘以相邻两根扫描线之间的距离即为扫描线扫过的面积,因此我们对y轴建一棵线段树(对所有线段的纵坐标离散化后建树),那么每条线段就可以用线段树中的一个区间来表示,每次扫到左边的边就在线段树中覆盖这条边对应的区间,扫到右边的边就在线段树中取消对这条边的覆盖,每扫过一根线段就维护一下扫描线被覆盖的长度即可
#include
#include
#include
#include
using namespace std;
#define ls (t<<1)
#define rs (t<<1)|1
#define eps 1e-8
#define f(a)for(int i=0;i b.flag;
else return a.x < b.x;
}
void build(int l, int r, int t)
{
e[t].l = l; e[t].r = r; e[t].num = 0; e[t].len = 0;
if (l + 1 == r)return;
int mid = (l + r) >> 1;
build(l, mid, ls);
build(mid, r, rs);
}
bool cc(double x, double y)
{
return fabs(x - y) < eps;
}
void update_len(int t)
{
if (e[t].num)e[t].len = y[e[t].r] - y[e[t].l];
else if (e[t].l + 1 == e[t].r)e[t].len = 0;
else e[t].len = e[ls].len + e[rs].len;
}
void update(double l, double r, int t, int z)
{
if (cc(y[e[t].l], l) && cc(y[e[t].r], r))e[t].num += z;
if (e[t].l + 1 < e[t].r)
{
int mid = (e[t].l + e[t].r) >> 1;
if (r <= y[mid] + eps)update(l, r, ls, z);
else if (l + eps >= y[mid])update(l, r, rs, z);
else {
update(l, y[mid], ls, z);
update(y[mid], r, rs, z);
}
}
update_len(t);
}
int main()
{
double xx, yy, x2, y2;
while (scanf("%lf%lf%lf%lf", &xx, &yy, &x2, &y2))
{
if (xx + yy + x2 + y2 == -4.0)break;
n = 0; no = 0;
while (1)
{
add(xx, yy, y2, yy, 1);
add(x2, yy, y2, y2, 0); n++;
scanf("%lf%lf%lf%lf", &xx, &yy, &x2, &y2);
if (xx + yy + x2 + y2 == -4.0)break;
}
sort(y, y + no);
sort(line, line + no, cmp);
int res = unique(y, y + no) - y;
build(0, res - 1, 1);
double ans = 0, len = 0;
f(no)
{
if (line[i].flag)update(line[i].y1, line[i].y2, 1, 1);
else update(line[i].y1, line[i].y2, 1, -1);
if (i)ans += len*(line[i].x - line[i - 1].x);
len = e[1].len;
}
printf("%.lf\n", ans);
}
}