您的位置:首页 > 其它

poj 1177 & hdu 1828 矩形周长并

2012-08-10 01:33 423 查看
线段树扫描线。。

思路 : 先将数据离散化,然后将 每个矩形看成 两条线段,分别为 左边的垂线段和 右边 垂线段,对所有的线段按 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);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: