http://acm.hdu.edu.cn/showproblem.php?pid=1255
利用线段树,求矩形面积的并,这个题目有一点不一样的是,求的面积必须要重叠的,用的了延迟标记和离散化……太菜了,调试了一个多小时才搞出来……
看来线段树的调试,最快的是在纸上运行,当然找找那些数据规模很小的,不然调试也很困难,这样的话就可以很容易的找出程序很多细节上的错误……
#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
using namespace std;
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
const int maxn=20100;
struct Line
{
double l,r,h;
int flag;
}line[10100];
int cmp(Line a,Line b)
{
return a.h < b.h;
}
double tab[20010];
bool equal(double a)
{
return fabs(a) < 1e-8;
}
int bin(double key,double tab[],int l,int r)
{
while(l<=r)
{
int m=(l+r)>>1;
if(equal(tab[m]-key)) return m;
else if(key<tab[m]) r=m-1;
else l=m+1;
}
}
double sum[maxn<<2];
int col[maxn<<2];
void pushdown(int rt,int l,int r)
{
if(l==r)
{
if(col[rt]==0||col[rt]==1) sum[rt]=0;
else sum[rt]=tab[r+1]-tab[l];
return;
}
if(col[rt]==0) return;
if(col[rt]>=2) sum[rt]=tab[r+1]-tab[l];
else
{
col[rt<<1]+=col[rt];
col[rt<<1|1]+=col[rt];
col[rt]=0;
int m=(l+r)>>1;
pushdown(rt<<1,l,m);
pushdown(rt<<1|1,m+1,r);
sum[rt]=sum[rt<<1]+sum[rt<<1|1];
}
}
void update(int L,int R,int d,int l,int r,int rt)
{
if(L<=l&&R>=r)
{
col[rt]+=d;;
pushdown(rt,l,r);
return;
}
pushdown(rt,l,r);
int m=(l+r)>>1;
if(L<=m) update(L,R,d,lson);
if(R>m) update(L,R,d,rson);
sum[rt]=sum[rt<<1]+sum[rt<<1|1];
}
int main()
{
int T,n;
double x1,x2,y1,y2;
scanf("%d",&T);
while(T--)
{
scanf("%d",&n);
for(int i=0;i<n;i++)
{
scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2);
line[2*i].l=x1,line[2*i].r=x2,line[2*i].h=y1,line[2*i].flag=1;
line[2*i+1].l=x1,line[2*i+1].r=x2,line[2*i+1].h=y2,line[2*i+1].flag=-1;
tab[2*i]=x1,tab[2*i+1]=x2;
}
sort(line,line+2*n,cmp);
sort(tab,tab+2*n);
int k=unique(tab,tab+2*n)-tab;
memset(col,0,sizeof(col));
memset(sum,0,sizeof(sum));
double ans=0;
for(int i=0;i<2*n-1;i++)
{
int l=bin(line[i].l,tab,0,k-1),r=bin(line[i].r,tab,0,k-1);
update(l,r-1,line[i].flag,0,k-2,1);
ans+=sum[1]*(line[i+1].h-line[i].h);
}
printf("%.2lf\n",ans);
}
return 0;
}