poj 1177 / hdu 1828 Picture 矩形周长并

来源:互联网 发布:中国文明知乎 编辑:程序博客网 时间:2024/06/08 17:31

分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;}


 

原创粉丝点击