#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define lson(i) (idx << 1)
#define rson(i) ((idx << 1) ^ 1)
using namespace std;
const int N = 1010;
double y[N];
struct segment{
double x, y1, y2;
int flag;
segment(){}
segment(const double x, const double y1, const double y2, const int flag){
this->x = x, this->y1 = y1, this->y2 = y2, this->flag = flag;
}
bool operator < (const segment &a) const {
return x < a.x;
}
}line[N];
struct segTree{
int lc, rc, cover;
double up, down, len;
}arr[N * 4];
void pushUp(int idx){
if(arr[idx].cover > 0)
arr[idx].len = arr[idx].up - arr[idx].down;
else
arr[idx].len = arr[lson(idx)].len + arr[rson(idx)].len;
}
void build(int idx, int l, int r){
arr[idx].lc = l, arr[idx].rc = r;
arr[idx].up = y[r], arr[idx].down = y[l];
arr[idx].len = arr[idx].cover = 0;
if(r - l == 1)
return ;
int mid = (l + r) >> 1;
/**
这里和普通的线段树有点不同,不能以左区间[1,mid],右区间[mid+1,r]来建树
如果这样建会漏掉一些线段,比如10,20,30,40这些点来建树,按普通的建法是
[10,20], [30,40],这样[20,30]这跟线段就漏掉了
所以需要左区间[l,mid],右区间[mid,r]这样来建;建出来是[10,20],[20,30],[30,40]
这样就没线段漏掉了.
**/
build(lson(idx), l, mid);
build(rson(idx), mid, r);
}
void update(int idx, int l, int r, int val){
if(arr[idx].lc > r || l > arr[idx].rc)
return ;
if(arr[idx].lc >= l && arr[idx].rc <= r){
arr[idx].cover += val;
pushUp(idx);
return ;
}
update(lson(idx), l, r, val);
update(rson(idx), l, r, val);
pushUp(idx);
}
int main(){
int n, no = 1;
while(cin >> n, n){
int i, idx = 1;
double x1, x2, y1, y2;
for(i = 1;i <= n;i++){
cin >> x1 >> y1 >> x2 >> y2;
line[idx] = segment(x1, y1, y2, 1);
y[idx++] = y1;
line[idx] = segment(x2, y1, y2, -1);
y[idx++] = y2;
}
sort(y + 1, y + idx);
sort(line + 1, line + idx);
/**以y轴建树**/
build(1, 1, idx - 1);
double res = 0;
for(i = 1;i < idx;i++){
res += arr[1].len * (line[i].x - line[i - 1].x);
/**二分出当前扫描线y1,y2的位置**/
int fir = lower_bound(y + 1, y + idx, line[i].y1) - y;
int sec = lower_bound(y + 1, y + idx, line[i].y2) - y;
update(1, fir, sec, line[i].flag);
}
printf("Test case #%d\nTotal explored area: %.2f\n\n", no++, res);
}
return 0;
}
线段树求矩形并模板
最新推荐文章于 2024-02-13 18:20:03 发布