HDU 1255 覆盖的面积

先将y轴坐标离散化,建树,再将线段横坐标按从小到大排序,从左到右插入,对于同一个矩形的两条对y轴平行的线段,左边的线段标记为-1,右边的线段标记为1,插入时判断y轴上这一段被覆盖的次数,成段更新这部分每太想明白,所以都直接更新到了根子叶,耗时比较长。

Problem Description
给定平面上若干矩形,求出被这些矩形覆盖过至少两次的区域的面积.


 

Input
输入数据的第一行是一个正整数T(1<=T<=100),代表测试数据的数量.每个测试数据的第一行是一个正整数N(1<=N<=1000),代表矩形的数量,然后是N行数据,每一行包含四个浮点数,代表平面上的一个矩形的左上角坐标和右下角坐标,矩形的上下边和X轴平行,左右边和Y轴平行.坐标的范围从0到100000.

注意:本题的输入数据较多,推荐使用scanf读入数据.
 
   
#include
#include
#include
int cmp1(const void *a,const void *b);
int cmp(const void *a,const void *b);
struct node
{
	int high,low;
	double x;
	int cover; //cover值存储被覆盖的面积
}stu[10000];
struct kode    //存储线段信息
{
	double x;
	int y1,y2;
	int flag;    //flag代表是左端还是右端

}line[10000];    
struct mode      //存储顶点信息,用于离散化中对纵坐标排序及建立映射
{ 
	double x,y;
	int flag;   
	int up;
}star[20000];
double ff[2100];   //存储映射
double ans;
void build(int low,int high,int x)
{
	stu[x].high=high;
	stu[x].low=low;
	stu[x].cover=0;
	stu[x].x=0;
	if(high==(low+1))
		return ;
	int mid=(high+low)/2;
	build(low,mid,2*x);    
	build(mid,high,x*2+1);   //对于求两点之间距离这种情况,建树时右儿子左端点不是mid+1,而是mid
}
void insert(int low,int high,double x,int flag,int n)
{
	
	if((stu[n].low+1)==stu[n].high)
	{
		if(stu[n].cover>1)
			ans+=(ff[stu[n].high]-ff[stu[n].low])*(x-stu[n].x);
		stu[n].cover+=flag;
		stu[n].x=x;
		return ;
	}
	if((stu[n].high==high)&&(stu[n].low==low))    //插入时更新到根子叶
	{
		insert(stu[n*2].low,stu[n*2].high,x,flag,n*2);
		insert(stu[n*2+1].low,stu[2*n+1].high,x,flag,n*2+1);
		return ;
	}
	if(low>=stu[2*n+1].low)
	{
		insert(low,high,x,flag,n*2+1);
	}
	
	else if(high<=stu[2*n].high)
	{
		insert(low,high,x,flag,n*2);
	}
	
	else
	{
		insert(low,stu[n*2].high,x,flag,n*2);
		insert(stu[n*2+1].low,high,x,flag,n*2+1);
	}
}
int main()
{
	int n,m,i,j,k,max,snum,f=1,t;
	double temp,x1,x2,y1,y2;
	scanf("%d",&t);
	while(t--)
	{
		scanf("%d",&n);
		snum=0;
		for(i=0;i0)
			{
				line[star[i].up-1].y2=max;   //利用顶点中存储的信息,将点还原成线段
				line[star[i].up-1].x=star[i].x;
				line[star[i].up-1].flag=star[i].flag;
			}
			else
			{
				line[-star[i].up-1].y1=max;
				line[-star[i].up-1].x=star[i].x;
				line[-star[i].up-1].flag=star[i].flag;
			}
		}
		build(1,max,1);
		qsort(line,2*n,sizeof(line[0]),cmp1);   //按x左边将线段排序,依次插入
		ans=0;
		for(i=0;iy)>(bb->y)?1:-1);
}

int cmp1(const void *a,const void *b)
{
	kode *aa=(kode *)a;
	kode *bb=(kode *)b;
	return ((aa->x)>(bb->x)?1:-1);
}



你可能感兴趣的:(HDU 1255 覆盖的面积)