#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
using namespace std;
struct node
{
int l,r,cnt,cover; //cover标记,1表示这个区间全部出现过了,0表示部分出现,-1表完全没出现过
double len;
}tree[605];
struct line
{
double l,r,y;
int f;
}L[205];
double x[205],Y;
int n,lx;
bool cmp(line a,line b)
{
return a.y<b.y;
}
int er_fen(double v)
{
int l=0,r=lx+1,mid;
while(r>l+1)
{
mid=(l+r)>>1;
if(v<x[mid]) r=mid;
else l=mid;
}
return l;
}
void build(int p,int l,int r)
{
tree[p].cover=-1;
if(l==r)
{
tree[p].len=x[l]-x[l-1];
return ;
}
int mid=(l+r)>>1;
build(p<<1,l,mid);
build((p<<1)|1,mid+1,r);
tree[p].len=tree[p<<1].len+tree[(p<<1)|1].len;
}
void add(int p,int l,int r,int x,int y,int sum)
{
if(l==r)
{
tree[p].cnt+=sum;
if(tree[p].cnt) tree[p].cover=1;
else tree[p].cover=-1;
return;
}
int mid=(l+r)>>1;
if(x<=mid) add(p<<1,l,mid,x,y,sum);
if(y>mid) add((p<<1)|1,mid+1,r,x,y,sum);
int k1=tree[p<<1].cover,k2=tree[(p<<1)|1].cover;
if(k1>0&&k2>0) tree[p].cover=1;
else if(k1<0&&k2<0) tree[p].cover=-1;
else tree[p].cover=0;
}
double query(int p,int l,int r)
{
if(tree[p].cover<0) return 0;
if(tree[p].cover>0) return tree[p].len;
int mid=(l+r)>>1;
return query(p<<1,l,mid)+query((p<<1)|1,mid+1,r);
}
int main()
{
int i,cnt,cas=0;
double x1,x2,y1,y2,ans;
while(scanf("%d",&n)!=EOF&&n)
{
cnt=0; ans=0;
for(i=1;i<=n;i++)
{
scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2);
x[cnt]=x1;
L[cnt].l=x1;
L[cnt].r=x2;
L[cnt].y=y1;
L[cnt++].f=1;
x[cnt]=x2;
L[cnt].l=x1;
L[cnt].r=x2;
L[cnt].y=y2;
L[cnt++].f=-1;
}
sort(x,x+cnt); //离散
sort(L,L+cnt,cmp);
lx=unique(x,x+cnt)-x-1; //去重
memset(tree,0,sizeof(tree));
build(1,1,lx);
for(i=0;i<cnt;i++)
{
ans+=query(1,1,lx)*(L[i].y-Y);
Y=L[i].y;
int l=er_fen(L[i].l)+1;
int r=er_fen(L[i].r);
if(L[i].f>0) add(1,1,lx,l,r,1);
else add(1,1,lx,l,r,-1);
}
printf("Test case #%d\n",++cas);
printf("Total explored area: %.2lf\n\n",ans);
}
}
线段树——扫描线
最新推荐文章于 2022-05-18 20:00:04 发布