对于扫描线与离散化的理解比较简单难点在与r-1与r+1的操作,对于一个区间左闭右开!!!
#include <iostream>
#include <vector>
#include <algorithm>
#include <cstring>
using namespace std;
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
const int MAXN=2222;
double sum[MAXN<<2];
int lazy[MAXN<<2];
struct Line
{
double l,r,h;
int s;
Line(){}
Line(double _l,double _r,double _h,int _s)
{
l=_l,r=_r,h=_h,s=_s;
}
bool operator <(const struct Line &a)const{
return h<a.h;
}
};
vector<Line> vt1;
vector<double> vt2;
void pushup(int l,int r,int rt)
{
if(lazy[rt]) sum[rt]=vt2[r+1]-vt2[l];
else if(l==r) sum[rt]=0;
else
sum[rt]=sum[rt<<1]+sum[rt<<1|1];
}
void update(int L,int R,int c,int l,int r,int rt)
{
if(L<=l&&r<=R)
{
lazy[rt]+=c;
pushup(l,r,rt);
return;
}
int mid=(l+r)>>1;
if(L<=mid) update(L,R,c,lson);
if(R>mid) update(L,R,c,rson);
pushup(l,r,rt);
}
int main()
{
int n;
int kace=1;
while(~scanf("%d",&n)&&n)
{
vt1.clear();
vt2.clear();
for(int i=0;i<n;i++)
{
double a,b,c,d;
scanf("%lf%lf%lf%lf",&a,&b,&c,&d);
vt2.push_back(a);
vt1.push_back(Line(a,c,b,1));
vt2.push_back(c);
vt1.push_back(Line(a,c,d,-1));
}
sort(vt2.begin(),vt2.end());
sort(vt1.begin(),vt1.end());
// build(0,vt2.size()-1,1);
vt2.erase(unique(vt2.begin(),vt2.end()),vt2.end());
// for(int i=0;i<vt1.size();i++)
// cout<<vt1[i].l<<" "<<vt1[i].r<<" "<<vt1[i].s<<" "<<vt1[i].h<<endl;
// for(int i=0;i<vt2.size();i++)
// cout<<vt2[i]<<endl;
double ans=0;
memset(sum,0,sizeof(sum));
memset(lazy,0,sizeof(lazy));
for(int i=0;i<vt1.size()-1;i++)
{
int l=lower_bound(vt2.begin(),vt2.end(),vt1[i].l)-vt2.begin();
int r=lower_bound(vt2.begin(),vt2.end(),vt1[i].r)-vt2.begin()-1;
update(l,r,vt1[i].s,0,vt2.size()-1,1);
// printf("%d\n",lazy[2]);
// printf("%lf\n",sum[1]*(vt1[i+1].h-vt1[i].h));
ans+=sum[1]*(vt1[i+1].h-vt1[i].h);
}
printf("Test case #%d\n",kace++);
printf("Total explored area: %.2lf\n\n",ans);
}
return 0;
}