线段树+离散化
代码
//By AcerMo
#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int M=3000;
struct Seg
{
double l,r,sum;
int lazy,so[2];
}t[M];
int cnt=2,n;
struct map{double x,y,yy;int flag;}p[M];
double s[M];
bool cmp(map a,map b){return a.x<b.x;}
void push_up(int x)
{
int ls=t[x].so[0];
int rs=t[x].so[1];
if(t[x].lazy>0) t[x].sum=t[x].r-t[x].l;
else t[x].sum=t[ls].sum+t[rs].sum;
return ;
}
void built(int l,int r,int x)
{
if(r-l==1)
{
t[x].l=s[l];t[x].r=s[r];
t[x].so[0]=t[x].so[1]=-1;
return (void)(t[x].sum=0);
}
t[x].l=s[l];t[x].r=s[r];
int mid=(l+r)>>1;
t[x].so[0]=++cnt;t[x].so[1]=++cnt;
built(l,mid,t[x].so[0]);built(mid,r,t[x].so[1]);
push_up(x);
return ;
}
void update(double y,double yy,int x,int flag)
{
if(t[x].l==y&&t[x].r==yy) return (void)(t[x].lazy+=flag,push_up(x));
if(t[t[x].so[0]].r>y)
update(y,min(t[t[x].so[0]].r,yy),t[x].so[0],flag);
if(t[t[x].so[1]].l<yy)
update(max(t[t[x].so[1]].l,y),yy,t[x].so[1],flag);
push_up(x);
return ;
}
int main()
{
int cas=1;
while(scanf("%d",&n)&&n)
{
double ans=0,x1,y,x2,yy;cnt=2;
for(int i=0;i<n;i++)
{
scanf("%lf%lf%lf%lf",&x1,&y,&x2,&yy);
p[i].x=x1;p[i].y=y;p[i].yy=yy;p[i].flag=1;
p[i+n].x=x2;p[i+n].y=y;p[i+n].yy=yy;p[i+n].flag=-1;
s[i+1]=y;s[i+n+1]=yy;
}
sort(s+1,s+(2*n+1));sort(p,p+2*n,cmp);
built(1,2*n,1);
update(p[0].y,p[0].yy,1,p[0].flag);
for(int i=1;i<2*n;i++)
{
ans+=(p[i].x-p[i-1].x)*t[1].sum;
update(p[i].y,p[i].yy,1,p[i].flag);
}
printf("Test case #%d\nTotal explored area: %.2lf\n\n",cas++,ans);
}
return 0;
}