#include<stdio.h>
#include<algorithm>
using namespace std;
struct line
{
double x1,y1,y2;
int isl;
}verl[257];
struct node
{
int l,r;
double len;
int covn;
};
node itree[1257];
double y[257];
bool operator < (const line &a,const line &b)
{
return a.x1<b.x1;
}
void ibuild(int id,int l,int r)
{
itree[id].l=l;
itree[id].r=r;
itree[id].len=0;
itree[id].covn=0;
if(l==r)
return ;
ibuild(id*2+1,l,(l+r)/2);
ibuild(id*2+2,(l+r)/2+1,r);
}
void iinsert(int id,int l,int r)
{
if(itree[id].l==l&&itree[id].r==r)
{
itree[id].len=y[r+1]-y[l];
++itree[id].covn;
return ;
}
if(r<(itree[id].l+itree[id].r)/2+1)
iinsert(id*2+1,l,r);
else if(l>(itree[id].l+itree[id].r)/2)
iinsert(id*2+2,l,r);
else
{
iinsert(id*2+1,l,(itree[id].l+itree[id].r)/2);
iinsert(id*2+2,(itree[id].l+itree[id].r)/2+1,r);
}
if(itree[id].covn==0)
itree[id].len=itree[id*2+1].len+itree[id*2+2].len;
}
void idelete(int id,int l,int r)
{
if(itree[id].l==l&&itree[id].r==r)
{
--itree[id].covn;
if(itree[id].covn==0)
{
if(itree[id].l==itree[id].r)
itree[id].len=0;
else
itree[id].len=itree[id*2+1].len+itree[id*2+2].len;
}
return ;
}
if(r<(itree[id].l+itree[id].r)/2+1)
idelete(id*2+1,l,r);
else if(l>(itree[id].l+itree[id].r)/2)
idelete(id*2+2,l,r);
else
{
idelete(id*2+1,l,(itree[id].l+itree[id].r)/2);
idelete(id*2+2,(itree[id].l+itree[id].r)/2+1,r);
}
if(itree[id].covn==0)
itree[id].len=itree[id*2+1].len+itree[id*2+2].len;
}
int binarys(double *y,int yl,double v)
{
int l,r,m;
int i,j,k;
l=0;r=yl-1;
while(l<yl)
{
m=(l+r)/2;
if(y[m]>v)
r=m-1;
else if(y[m]<v)
l=m+1;
else
return m;
}
return -1;
}
int main()
{
int n;
double x1,x2,y1,y2;
double res=0;
int l,r;
int i,j,k;
int ii;
k=0;
while(~scanf("%d",&n)&&n)
{
i=-1;
do
{
scanf("%lf %lf %lf %lf",&x1,&y1,&x2,&y2);
y[++i]=y1;
verl[i].x1=x1;verl[i].y1=y1;verl[i].y2=y2;verl[i].isl=1;
y[++i]=y2;
verl[i].x1=x2;verl[i].y1=y1;verl[i].y2=y2;verl[i].isl=0;
}while(--n);
sort(y,y+i+1);
ii=unique(y,y+i+1)-y;
ibuild(0,0,ii-1-1);
sort(verl,verl+i+1);
res=0;
for(j=i,i=0;i<j;++i)
{
l=binarys(y,ii,verl[i].y1);
r=binarys(y,ii,verl[i].y2);
if(verl[i].isl)
iinsert(0,l,r-1);
else
idelete(0,l,r-1);
res+=itree[0].len*(verl[i+1].x1-verl[i].x1);
}
printf("Test case #%d\nTotal explored area: %.2f\n\n",++k,res);
}
return 0;
}
规定矩形的位置用矩形的左下角和右上角坐标表示,给定矩形,要求给出被矩形覆盖的面积并。想象在坐标系里的 1 根扫描线,向 1 个方向扫描的时候每碰到矩形的 1 条边即停下(矩形坐标的 x 点),计算这条边和上条边间的面积(两边 x 点之差 * 更新线段树统计的区间)。
算法《 https://wswmsword.github.io/2019/06/06/线段树/ 》
算法《折半查找》