题目来源:HDU 1542 Atlantis
题意:给你一些矩形(左下角和右上角)求面积
思路:参考here这个超赞的 一看就懂了
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cctype>
using namespace std;
const int maxn = 210;
struct node
{
double l, r, h;
int s, val;
node(){}
node(double a, double b, double c, int d) : l(a), r(b), h(c), s(d) {}
}seg[2*maxn];
double sum[maxn<<2];
double X[2*maxn];
int len[maxn<<2];
struct Point
{
double x;
int id, v;
}b[2*maxn];
bool cmp(node a, node b)
{
return a.h < b.h;
}
bool cmp1(Point a, Point b)
{
return a.x < b.x;
}
bool cmp2(Point a, Point b)
{
return a.id < b.id;
}
void pushup(int rt, int l, int r)
{
if(len[rt])
sum[rt] = X[r+1] - X[l];
else if(l == r)
sum[rt] = 0;
else
sum[rt] = sum[rt<<1] + sum[rt<<1|1];
}
void update(int x, int y, int l, int r, int rt, int c)
{
if(x == l && y == r)
{
len[rt] += c;
pushup(rt, l, r);
return;
}
int m = (l + r) >> 1;
if(y <= m)
update(x, y, l, m, rt<<1, c);
else if(x > m)
update(x, y, m+1, r, rt<<1|1, c);
else
{
update(x, m, l, m, rt<<1, c);
update(m+1, y, m+1, r, rt<<1|1, c);
}
pushup(rt, l, r);
}
int main()
{
int cas = 1;
int n;
while(scanf("%d", &n) && n)
{
int m = 0, k = 1;
for(int i = 0; i < n; i++)
{
double a, b, c, d;
scanf("%lf %lf %lf %lf", &a, &b, &c, &d);
seg[m++] = node(a, c, b, 1);
seg[m++] = node(a, c, d, -1);
X[k++] = a;
X[k++] = c;
}
sort(seg, seg+m, cmp);
for(int i = 0; i < m; i++)
{
b[i<<1].x = seg[i].l;
b[i<<1].id = i<<1;
b[i<<1|1].x = seg[i].r;
b[i<<1|1].id = i<<1|1;
}
sort(b, b+2*m, cmp1);
int num = 1;
double now = b[0].x;
for(int i = 0; i < 2*m; i++)
{
if(b[i].x != now)
{
num++;
now = b[i].x;
}
b[i].v = num;
}
sort(b, b+2*m, cmp2);
double s = 0;
memset(sum, 0, sizeof(sum));
memset(len, 0, sizeof(len));
sort(X+1, X+k);
k = 1;
for(int i = 2; i <= m; i++)
{
if(X[i] != X[i-1])
X[++k] = X[i];
}
for(int i = 0; i < m-1; i++)
{
int l = b[i<<1].v;
int r = b[i<<1|1].v-1;
if(l <= r)
update(l, r, 1, num, 1, seg[i].s);
s += sum[1] * (seg[i+1].h - seg[i].h);
}
printf("Test case #%d\n", cas++);
printf("Total explored area: %.2f\n\n", s);
}
return 0;
}