注意点:
- 需要将y轴坐标离散化后映射到线段树上.
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<map>
using namespace std;
const int MAXN=2e5;
struct Point{
double x,y,z;
int k;
bool operator <(Point another)const{
return x<another.x;
}
}a[MAXN];
struct Line{
int l,r,cnt;
double len;
}tr[MAXN<<3];
void build(int p,int l,int r){
tr[p].l=l,tr[p].r=r,tr[p].cnt=0,tr[p].len=0;
if(l!=r){
int mid=(l+r)>>1;
build(p<<1,l,mid);
build((p<<1)|1,mid+1,r);
}
}
double raw[MAXN<<1];
void change(int p,int l,int r,double val){
if(tr[p].l>=l&&tr[p].r<=r){
tr[p].cnt+=val;
if(tr[p].cnt){
tr[p].len=raw[tr[p].r+1]-raw[tr[p].l];
}else{
if(tr[p].l!=tr[p].r){
tr[p].len=tr[p<<1].len+tr[(p<<1)|1].len;
}else tr[p].len=0;
}
return;
}
int mid=(tr[p].l+tr[p].r)>>1;
if(l<=mid)change(p<<1,l,r,val);
if(r>mid)change((p<<1)|1,l,r,val);
tr[p].len=tr[p].cnt?raw[tr[p].r+1]-raw[tr[p].l]:tr[p<<1].len+tr[(p<<1)|1].len;
}
map<double,int> val;
int root=1;
int main(){
int caseCnt=0;
while(1){
int n;
scanf("%d",&n);
if(n==0)break;
for(int i=1;i<=n;i++){
int k=i*2;
double y,z;
scanf("%lf%lf%lf%lf",&a[k-1].x,&y,&a[k].x,&z);
raw[k-1]=a[k-1].y=a[k].y=y;
raw[k]=a[k-1].z=a[k].z=z;
a[k-1].k=1,a[k].k=-1;
}
n=n<<1;
sort(raw+1,raw+n+1);
int m=unique(raw+1,raw+1+n)-(raw+1);
for(int i=1;i<=m;i++)val[raw[i]]=i;
sort(a+1,a+1+n);
build(root,1,m-1);
double ans=0;
for(int i=1;i<=n-1;i++){
int y=val[a[i].y],z=val[a[i].z]-1;
change(root,y,z,a[i].k);
ans+=tr[root].len*(a[i+1].x-a[i].x);
}
printf("Test case #%d
",++caseCnt);
printf("Total explored area: %.2f
",ans);
}
return 0;
}