您的位置:首页 > 其它

poj 1177 / hdu 1828 Picture 矩形周长并

2012-08-11 14:06 357 查看
分x边和y边两次线段树扫描线,寻找cover值0->1的区域,长度*2即可。

#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <iostream>
using namespace std;
const int maxn=20005;
const int TT=10000;
int n;
struct rect{
int x1, y1, x2, y2;
}rec[maxn];
struct node{
int lef, rig, mid, cover;
}seg[maxn*4];

struct line{
int x1, x2, y, flag;
}l[maxn];

void make_tree(int num, int lef, int rig){
seg[num].lef=lef;
seg[num].rig=rig;
seg[num].mid=(lef+rig)/2;
seg[num].cover=0;
if(lef+1!=rig){
make_tree(num*2, lef, seg[num].mid);
make_tree(num*2+1, seg[num].mid, rig);
}
}

int insert(int num, int lef, int rig, int cover, int f){
if(seg[num].cover!=-1&&seg[num].lef==lef&&seg[num].rig==rig){
if(cover==1&&seg[num].cover==0&&f){
seg[num].cover+=cover;
return seg[num].rig-seg[num].lef;
}
seg[num].cover+=cover;
return 0;
}
if(seg[num].cover>0){
insert(num*2, seg[num].lef, seg[num].mid, seg[num].cover, 0);
insert(num*2+1, seg[num].mid, seg[num].rig, seg[num].cover, 0);
seg[num].cover=-1;
}
seg[num].cover=-1;
if(rig<=seg[num].mid)
return insert(num*2, lef, rig, cover, f);
else if(lef>=seg[num].mid)
return insert(num*2+1, lef, rig, cover, f);
else {
return insert(num*2, lef, seg[num].mid, cover, f)+
insert(num*2+1, seg[num].mid, rig, cover, f);
}
}

void init(int t){
for(int i=0; i<n; i++){
if(t==1){
l[i*2].x1=rec[i].x1; l[i*2].y=rec[i].y1; l[i*2+1].x2=rec[i].x2;  l[i*2+1].y=rec[i].y2;
}
else {
l[i*2].x1=rec[i].y1; l[i*2].y=rec[i].x1; l[i*2+1].x2=rec[i].y2;  l[i*2+1].y=rec[i].x2;
}
l[i*2].x1+=TT; l[i*2].y+=TT; l[i*2+1].x2+=TT; l[i*2+1].y+=TT;
l[i*2].x2=l[i*2+1].x2;
l[i*2+1].x1=l[i*2].x1;
l[i*2].flag=1;
l[i*2+1].flag=-1;
}
}
bool cmpy(line l1, line l2){
return l1.y<l2.y;
}

int solve(){
int ans=0;
make_tree(1, 0, TT*2);
sort(l, l+2*n, cmpy);
for(int i=0; i<2*n-1; i++){
ans+=2*insert(1, l[i].x1, l[i].x2, l[i].flag, 1);
}
return ans;
}

int main(){
//freopen("1.txt", "r", stdin);
while(scanf("%d", &n)!=EOF){
for(int i=0; i<n; i++)
scanf("%d%d%d%d", &rec[i].x1, &rec[i].y1, &rec[i].x2, &rec[i].y2);
init(1);
int ans=solve();
init(2);
ans+=solve();
printf("%d\n", ans);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: