模板,线段树,矩形轮廓周长

// poj 1177 矩形轮廓周长
// by utoppia

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;

#define lson (u<<1)
#define rson ((u<<1)+1)
#define nMax 40010

int len[nMax<<2],cov[nMax << 2],cnt[nMax << 2],lcov[nMax<<2],rcov[nMax<<2];
struct Node{
    int l,r,m;
    void build(int a,int b){
        l=a,r=b;
        m = (l+r) >> 1;
    }
} node[nMax << 2];

void setlen(int u) {
    if(cov[u]>0) {
        len[u] = node[u].r - node[u].l;
        lcov[u] = rcov[u] = 1;
        cnt[u] = 1;
        return ;
    }
    if(node[u].r == node[u].l+1) {
        len[u]=0;
        lcov[u]=rcov[u]=cnt[u]=0;
    }else {
        len[u] = len[lson] + len[rson];
        lcov[u] = lcov[lson];
        rcov[u] = rcov[rson];
        cnt[u] = cnt[lson]+cnt[rson]-rcov[lson]*lcov[rson];
    }

}
void build(int u,int l,int r){
    node[u].build(l,r);
    cov[u] = len[u] = cnt[u] = lcov[u] = rcov[u] = 0;
    if(l+1 == r) return ;
    int m = (l+r) >> 1;
    build(lson,l,m);
    build(rson,m,r);
}
void ins(int u,int l,int r,int k) {
    if(node[u].l==l && node[u].r==r) {
        cov[u]+=k;
        setlen(u);
        return ;
    }
    int m = node[u].m;
    if(r<=m) ins(lson,l,r,k);
    else if(l>=m) ins(rson,l,r,k);
    else {
        ins(lson,l,m,k);
        ins(rson,m,r,k);
    }
    setlen(u);
}
struct Seg{
    int x[2],y,flag;
    void set(int x1,int x2,int _y,int k) {
        x[0]=x1;x[1]=x2;y=_y;flag=k;
    }
    bool operator < (const Seg& a) const { return y < a.y;}
} seg[nMax];

int const inf = 10010;
int inline max(int x,int y){ return x > y ? x : y; }
int inline abs(int x) { if(x<0) x=-x;return x;}

int n,xl,xr,yl,yr;
int main() {
    while(~scanf("%d",&n)){
        int m = 0;
        int L = 0;
        for(int i=0;i<n;i++) {
            scanf("%d%d%d%d",&xl,&yl,&xr,&yr);
            xl += inf;
            xr += inf;
            L = max(L,xl);L = max(L,xr);
            seg[m++].set(xl,xr,yl,1);
            seg[m++].set(xl,xr,yr,-1);
        }
        build(1,0,L);
        sort(seg,seg+m);
        int now = 0,ans=0;
        for(int i=0;i<m-1;i++) {
            ins(1,seg[i].x[0],seg[i].x[1],seg[i].flag);
            ans += abs(len[1]-now);
            ans += 2*(seg[i+1].y-seg[i].y)*cnt[1];
            now = len[1];
        }
        ins(1,seg[m-1].x[0],seg[m-1].x[1],seg[m-1].flag);
        ans += abs(len[1]-now);
        printf("%d\n",ans);
    }
    return 0;
}

原理和面积并是一样的,注意有了两边的长要计算;

POJ 1177 Picture



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值