Poj1177(求矩形並的輪廓周長)

題目鏈接:http://poj.org/problem?id=1177

 

題意:給出多個矩形,求這些矩形所覆蓋圖形的周長。

 

可用線段樹來做,兩種方法:

1、分別對x和y方向離散化後做線段樹,求出各方向上的輪廓長;

2、對一個方向上的座標進行離散化,用另一維進行掃描;

 

其中,第二個方法要在線段樹中維護的值域包括:

1、覆蓋的線段長度;

2、不相邊的線段數;

3、該節點表示的區間兩端點是否被覆蓋(用於合併線段);

 

Code

#include<stdio.h>
#include<string.h>
#include<stdlib.h>

#define M 20008
#define L(x) (x<<1)
#define R(x) (x<<1|1)
#define Mid(x,y) ((x+y)>>1)
typedef struct{
	int l,r;
	int len,c,a;
	char lc,rc;
	void init(){
		l=r=len=c=a=0;
		lc=rc=0;
	}
}SegT;
typedef struct Line{
	int x,y0,y1;
	char f;
	Line(){}
	Line(int _x,int _y0,int _y1,char _f)
	{
		set(_x,_y0,_y1,_f);
	}
	void set(int _x,int _y0,int _y1,char _f)
	{
		x=_x;y0=_y0;y1=_y1;f=_f;
	}
}Line;
SegT t[M<<2];
Line ls[M];
int ys[M];
int yn;
int n;
int ans,len;

int Abs(int a)
{
	return a<0?-a:a;
}

int Cmpy(const void *a,const void *b)
{
	return *(int *)a-*(int *)b;
}

int Cmpl(const void *a,const void *b)
{
	Line *p=(Line *)a;
	Line *q=(Line *)b;
	if(p->x==q->x)
		return q->f-p->f;
	return p->x-q->x;
}

void Create(int i,int lt,int rt)
{
	int mid;
	t[i].init();
	t[i].l=lt;t[i].r=rt;
	if(lt+1<rt){
		mid=Mid(lt,rt);
		Create(L(i),lt,mid);
		Create(R(i),mid,rt);
	}
}
void Cal(int i)
{
	if(t[i].c>0){
		t[i].a=1;
		t[i].lc=t[i].rc=1;
		t[i].len=ys[t[i].r]-ys[t[i].l];
	}
	else if(t[i].l+1==t[i].r){
		t[i].a=0;t[i].len=0;
		t[i].lc=t[i].rc=0;
	}
	else{
		t[i].a=t[L(i)].a+t[R(i)].a-(t[L(i)].rc&t[R(i)].lc);
		t[i].len=t[L(i)].len+t[R(i)].len;
		t[i].lc=t[L(i)].lc;t[i].rc=t[R(i)].rc;
	}
}

void Updata(int i,Line l)
{
	int mid;

	if(t[i].l+1==t[i].r){
		t[i].c+=l.f;
		Cal(i);
		return ;
	}
	mid=Mid(t[i].l,t[i].r);
	if(l.y1<=ys[mid])
		Updata(L(i),l);
	else if(l.y0>=ys[mid])
		Updata(R(i),l);
	else{
		Updata(L(i),Line(l.x,l.y0,ys[mid],l.f));
		Updata(R(i),Line(l.x,ys[mid],l.y1,l.f));
	}
	Cal(i);
}

int main()
{
	int i,j;
	int xo,xl,yo,yl;
		
	while(~scanf("%d",&n)){
		for(i=0;i<n;i++){
			scanf("%d%d%d%d",&xo,&yo,&xl,&yl);
			ls[L(i)].set(xo,yo,yl,1);
			ls[R(i)].set(xl,yo,yl,-1);
			ys[L(i)]=yo;ys[R(i)]=yl;
		}
		qsort(ys,L(n),sizeof(ys[0]),Cmpy);
		qsort(ls,L(n),sizeof(ls[0]),Cmpl);

		for(i=j=0,n<<=1;i<n;i++){
			if(ys[i]==ys[j]) continue;
			ys[++j]=ys[i];
		}yn=++j;

		Create(1,0,yn);
		Updata(1,ls[0]);
		ans=len=0;
		for(i=1;i<n;i++){
			ans+=(ls[i].x-ls[i-1].x)*t[1].a*2;
			ans+=Abs(len-t[1].len);
			len=t[1].len;
			Updata(1,ls[i]);
		}ans+=len;
		printf("%d\n",ans);
	}
	return 0;
}


 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章