Problem Description
给定平面上若干矩形,求出被这些矩形覆盖过至少两次的区域的面积.
Input
输入数据的第一行是一个正整数T(1<=T<=100),代表测试数据的数量.每个测试数据的第一行是一个正整数N(1<=N<=1000),代表矩形的数量,然后是N行数据,每一行包含四个浮点数,代表平面上的一个矩形的左上角坐标和右下角坐标,矩形的上下边和X轴平行,左右边和Y轴平行.坐标的范围从0到100000.
注意:本题的输入数据较多,推荐使用scanf读入数据.
Output
对于每组测试数据,请计算出被这些矩形覆盖过至少两次的区域的面积.结果保留两位小数.
Sample Input
2
5
1 1 4 2
1 3 3 7
2 1.5 5 4.5
3.5 1.25 7.5 4
6 3 10 7
3
0 0 1 1
1 0 2 1
2 0 3 1
Sample Output
7.63
0.00
求多重覆盖的面积,在矩形面积并的基础上稍作修改就ok了,主要修改的是线段树统计的部分
#include<cstdio>标签:insert,HDU,覆盖,int,sum,mid,else,1255,dis From: https://blog.51cto.com/u_15870896/5838717
#include<cmath>
#include<map>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long LL;
const int maxn = 400005;
int n, m, T;
double l, r, a[maxn], ans;
struct seg
{
double h, l, r;
int k;
bool operator <(const seg&a)
{
return h < a.h;
}
}p[maxn];
struct ST
{
double dis[maxn][2];
int sum[maxn];
void build(int x, int l, int r)
{
sum[x] = dis[x][0] = dis[x][1] = 0;
if (l == r) return;
else
{
int mid = l + r >> 1;
build(x + x, l, mid);
build(x + x + 1, mid + 1, r);
}
}
void insert(int x, int l, int r, int ll, int rr, int v)
{
if (ll <= l&&r <= rr)
{
if (v < 0 && sum[x] == 0) goto next;
sum[x] += v;
if (sum[x] == 0)
{
if (l == r) dis[x][1] = dis[x][0] = 0;
else
{
dis[x][1] = dis[x + x][1] + dis[x + x + 1][1];
dis[x][0] = dis[x + x][0] + dis[x + x + 1][0];
}
}
else if (sum[x] == 1)
{
if (l == r) dis[x][1] = 0, dis[x][0] = a[r + 1] - a[l];
else
{
dis[x][1] = dis[x + x][1] + dis[x + x + 1][1] + dis[x + x][0] + dis[x + x + 1][0];
dis[x][0] = a[r + 1] - a[l] - dis[x][1];
}
}
else dis[x][0] = 0, dis[x][1] = a[r + 1] - a[l];
}
else
{
next:
int mid = l + r >> 1;
if (sum[x])
{
insert(x + x, l, mid, l, r, sum[x]);
insert(x + x + 1, mid + 1, r, l, r, sum[x]);
sum[x] = 0;
}
if (ll <= mid) insert(x + x, l, mid, ll, rr, v);
if (rr > mid) insert(x + x + 1, mid + 1, r, ll, rr, v);
dis[x][1] = dis[x + x][1] + dis[x + x + 1][1];
dis[x][0] = dis[x + x][0] + dis[x + x + 1][0];
}
}
}st;
int main()
{
scanf("%d", &T);
while (T--)
{
scanf("%d", &n);
for (int i = 1; i <= n; i++)
{
scanf("%lf%lf%lf%lf", &l, &p[i + i - 1].h, &r, &p[i + i].h);
p[i + i - 1].l = p[i + i].l = a[i + i - 1] = l;
p[i + i - 1].r = p[i + i].r = a[i + i] = r;
p[i + i - 1].k = 1; p[i + i].k = -1;
}
sort(a + 1, a + n + n + 1);
m = unique(a + 1, a + n + n + 1) - a;
sort(p + 1, p + n + n + 1);
ans = 0; st.build(1, 1, m - 2);
for (int i = 1; i <= n + n; i++)
{
int u = lower_bound(a + 1, a + m, p[i].l) - a;
int v = lower_bound(a + 1, a + m, p[i].r) - a;
st.insert(1, 1, m - 2, u, v - 1, p[i].k);
ans += (p[i + 1].h - p[i].h)*st.dis[1][1];
}
printf("%.2lf\n", ans);
}
return 0;
}