hdu 1542 线段树 求面积并
View Code
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
const int maxn = 1000;
double sum[maxn<<2];
int cover[maxn<<2];
double x[maxn];
struct seg{
double l,r,h;
int flag;
seg(){}
seg(double _l,double _r,double _h,int _flag):l(_l),r(_r),h(_h),flag(_flag){}
bool operator <(const seg &cmp) const {
return h<cmp.h;
}
}horizontal_seg[maxn];
void pushup(int rt,int l,int r)
{
if(cover[rt]){
sum[rt]=x[r+1]-x[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){
cover[rt]+=c;
pushup(rt,l,r);
return ;
}
int m=(l+r)>>1;
if(L<=m) update(L,R,c,lson);
if(R>m) update(L,R,c,rson);
pushup(rt,l,r);
}
int bin(double key,int n,double x[]){
int l=0,r=n-1,mid,best=-1;
while(l<=r){
mid=(l+r)>>1;
if(x[mid]<=key){
best=mid;
l=mid+1;
}
else r=mid-1;
}
return best;
}
int main()
{
int n,i,j,tot,cases=1;
double x1,y1,x2,y2;
while(scanf("%d",&n),n)
{
tot=0;
for(i=1;i<=n;i++)
{
scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2);
x[tot]=x1;
horizontal_seg[tot++]=seg(x1,x2,y1,1);
x[tot]=x2;
horizontal_seg[tot++]=seg(x1,x2,y2,-1);
}
sort(x,x+tot);
sort(horizontal_seg,horizontal_seg+tot);
for(i=1,j=1;i<tot;i++){
if(x[i]!=x[i-1]) x[j++]=x[i];
}
memset(cover , 0 , sizeof(cover));
memset(sum , 0 , sizeof(sum));
double area=0;
for(i=0;i<tot-1;i++)
{
int left=bin(horizontal_seg[i].l,j,x);
int right=bin(horizontal_seg[i].r,j,x)-1;
update(left,right,horizontal_seg[i].flag,0,j-1,1);
area+=sum[1]*(horizontal_seg[i+1].h-horizontal_seg[i].h);
}
printf("Test case #%d\n",cases++);
printf("Total explored area: %.2lf\n\n",area);
}
return 0;
}