题目大意:N个矩形,求矩形面积的并。
解题思路:线段树扫描线的裸题。
#include <cstdio>
#include <cstring>
#include <vector>
#include <algorithm>
using namespace std;
const int maxn = 1005;
#define lson(x) ((x)<<1)
#define rson(x) (((x)<<1)|1)
int lc[maxn << 2], rc[maxn << 2], v[maxn << 2];
double s[maxn << 2];
vector<double> pos;
inline void pushup(int u) {
if (v[u])
s[u] = pos[rc[u] + 1] - pos[lc[u]];
else if (rc[u] == lc[u])
s[u] = 0;
else
s[u] = s[lson(u)] + s[rson(u)];
}
inline void add(int u, int set) {
v[u] += set;
pushup(u);
}
void build (int u, int l, int r) {
lc[u] = l;
rc[u] = r;
v[u] = 0;
s[u] = 0;
if (l == r)
return;
int mid = (l + r) / 2;
build(lson(u), l, mid);
build(rson(u), mid + 1, r);
pushup(u);
}
void modify (int u, int l, int r, int set) {
if (l <= lc[u] && rc[u] <= r) {
add(u, set);
return;
}
int mid = (lc[u] + rc[u]) / 2;
if (l <= mid)
modify(lson(u), l, r, set);
if (r > mid)
modify(rson(u), l, r, set);
pushup(u);
}
struct segment {
double x;
int l, r, set;
segment (double x = 0, int l = 0, int r = 0, int set = 0) {
this->x = x;
this->l = l;
this->r = r;
this->set = set;
}
};
int N;
vector<segment> vec;
double x1[maxn], x2[maxn], y1[maxn], y2[maxn];
inline bool cmp (const segment& a, const segment& b) {
return a.x < b.x;
}
inline int find (double k) {
return lower_bound(pos.begin(), pos.end(), k) - pos.begin();
}
int main () {
int cas = 1;
while (scanf("%d", &N) == 1 && N) {
double ans = 0;
vec.clear();
pos.clear();
for (int i = 0; i < N; i++) {
scanf("%lf%lf%lf%lf", &x1[i], &y1[i], &x2[i], &y2[i]);
pos.push_back(y1[i]);
pos.push_back(y2[i]);
}
sort(pos.begin(), pos.end());
build(1, 0, pos.size() * 2 - 1);
for (int i = 0; i < N; i++) {
vec.push_back(segment(x1[i], find(y1[i]), find(y2[i]) - 1, 1));
vec.push_back(segment(x2[i], find(y1[i]), find(y2[i]) - 1, -1));
}
sort(vec.begin(), vec.end(), cmp);
for (int i = 0; i < vec.size() - 1; i++) {
modify(1, vec[i].l, vec[i].r, vec[i].set);
ans += (s[1] * (vec[i+1].x - vec[i].x));
}
printf("Test case #%d\n", cas++);
printf("Total explored area: %.2lf\n\n", ans);
}
return 0;
}

本文介绍了一道经典的线段树扫描线算法题HDU1542 Atlantis,并提供了完整的C++实现代码。该算法用于解决多个矩形面积并集的问题,通过对矩形边界的遍历及线段树维护区间状态来高效计算总面积。

1445

被折叠的 条评论
为什么被折叠?



