x,y两维,hashx并按y排序做扫描线
#include<iostream>
#include<string.h>#include<algorithm>
#include<stdio.h>
#include<map>
#define lson (id*2)
#define rson (id*2+1)
using namespace std;
map<double,int> hashx;
int n,Case;
double ans,x[250];
struct tree
{
int val;//每组询问仅100个点,无需lazy
double len;
}t[1000];
struct edge
{
int l,r,v;
double y,x1,x2;
}e[250];
int cmp(edge a,edge b)
{
return a.y<b.y;
}
void pushup(int id)
{
t[id].len=t[lson].len+t[rson].len;
}
void insert(int id,int l,int r,int L,int R,int v)
{//注意lr的区间所代表的真实值,端点-1之类的要考虑好
if (r<L || R<l) return;if (l==r)
{
t[id].val+=v;
//cout<<t[id].val<<endl;
if (t[id].val<=0)
t[id].len=0;
else
t[id].len=x[r+1]-x[l];
return;
}
int mid=(l+r)/2;
insert(lson,l,mid,L,R,v);
insert(rson,mid+1,r,L,R,v);
pushup(id);
}
int main()
{
while (cin>>n)
{
if (n==0) return 0;
//初始化
ans=0;
memset(t,0,sizeof(t));
memset(e,0,sizeof(e));
memset(x,0,sizeof(x));
hashx.clear();
//读入
for (int i=1;i<=n;i++)
{
double x1,y1,x2,y2;
scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2);
x[i]=e[i].x1=e[i+n].x1=x1;
x[i+n]=e[i].x2=e[i+n].x2=x2;
e[i].y=y1;
e[i+n].y=y2;
e[i].v=1;
e[i+n].v=-1;
}
//预处理&hash
sort(x+1,x+1+2*n);
sort(e+1,e+1+2*n,cmp);
for (int i=1;i<=2*n;i++)
hashx[x[i]]=i;
for (int i=1;i<=2*n;i++)
{
e[i].l=hashx[e[i].x1];
e[i].r=hashx[e[i].x2];
}
//操作:按y扫描
for (int i=1;i<=2*n;i++)
{
double w=e[i].y-e[i-1].y;
ans+=w*t[1].len;
//cout<<t[1].len<<endl;
while(e[i].y==e[i+1].y)
{//注意同y的边要全扫完在进行下一个
insert(1,1,2*n,e[i].l,e[i].r-1,e[i].v);
i++;
}
insert(1,1,2*n,e[i].l,e[i].r-1,e[i].v);
}
//输出
printf("Test case #%d\nTotal explored area: %.2f\n\n",++Case,ans);
}
}