现在的位置: 首页 > 综合 > 正文

poj 1177 & hdu 1828 矩形周长并

2014年03月13日 ⁄ 综合 ⁄ 共 1871字 ⁄ 字号 评论关闭

线段树扫描线。。

思路 : 先将数据离散化,然后将 每个矩形看成 两条线段,分别为 左边的垂线段和 右边 垂线段,对所有的线段按 x 坐标进行排序,依次插入到 线段树中。

线段树需要记录 的内容 为 len ->当前区间被线段覆盖的长度,cnt->当前区间内 包含的 连续子线段数,lbd,rbd-> 当前区间左边界和右边界,cover->覆盖标记。

lbd 和 rbd 是判断 是否两条线段可以合并成一条线段

#include<iostream>
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<algorithm>
using namespace std;

#define lson u<<1
#define rson u<<1|1
#define MAXN 10005

int ycoord[MAXN];

struct SEG {
	int ly,hy,x,cover;
	SEG(){}
	SEG(int a,int b,int c,int d):ly(a),hy(b),x(c),cover(d){}
	bool operator < (const SEG& cmp)const{
		return x<cmp.x;
	}
}seg[MAXN];

struct Node{
	int lef,rig;
	int lbd,rbd,cnt,len;
	int cover;
}T[MAXN<<2];

void Build(int u,int l,int r){
	T[u].lef=l;
	T[u].rig=r;
	T[u].cnt=T[u].len=0;
	T[u].cover=0;
	T[u].lbd=T[u].rbd=0;
	if(l+1==r)return;
	int mid=(l+r)>>1;
	Build(lson,l,mid);
	Build(rson,mid,r);
}

void PushUp(int u){
	if(T[u].cover){
		T[u].lbd=T[u].rbd=1;
		T[u].len=ycoord[T[u].rig]-ycoord[T[u].lef];
		T[u].cnt=1;
	}
	else if(T[u].lef+1==T[u].rig){
		T[u].len=T[u].cnt=0;
		T[u].lbd=T[u].rbd=0;
	}
	else {
		T[u].lbd=T[lson].lbd;
		T[u].rbd=T[rson].rbd;
		T[u].len=T[lson].len+T[rson].len;
		T[u].cnt=T[lson].cnt+T[rson].cnt;
		if(T[lson].rbd&&T[rson].lbd)T[u].cnt--;
	}
}

void Update(int u,int l,int r,int cover){
	if(r<T[u].lef||T[u].rig<l)return;
	if(l<=T[u].lef&&T[u].rig<=r){
		T[u].cover+=cover;
	}
	else {
		if(l<=T[lson].rig)Update(lson,l,r,cover);
		if(r>=T[rson].lef)Update(rson,l,r,cover);
	}
	PushUp(u);
}

int main(){
	int n;
	while(scanf("%d",&n)==1){
		int x1,y1,x2,y2;
		int cnt=0;
		for(int i=0;i<n;i++){
			scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
			ycoord[cnt]=y1;
			seg[cnt++]=SEG(y1,y2,x1,1);
			ycoord[cnt]=y2;
			seg[cnt++]=SEG(y1,y2,x2,-1);
		}
		sort(ycoord,ycoord+cnt);
		sort(seg,seg+cnt);
		int num=unique(ycoord,ycoord+cnt)-ycoord;
		Build(1,0,num);
		int sumprt=0;
		int prelen=0;
		for(int i=0;i<cnt;i++){
			int ll=lower_bound(ycoord,ycoord+num,seg[i].ly)-ycoord;
			int rr=lower_bound(ycoord,ycoord+num,seg[i].hy)-ycoord;
			Update(1,ll,rr,seg[i].cover);
			sumprt+=abs(T[1].len-prelen);
			sumprt+=2*T[1].cnt*(seg[i+1].x-seg[i].x);
			prelen=T[1].len;
		}
		printf("%d\n",sumprt);
	}
}

抱歉!评论已关闭.