POJ - 1177 Picture (扫描线,扫描周长的板子)

Picture

#include<cstring>
#include<algorithm>
#include<iostream>
#include<cstdio>
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
using namespace std;
const int X = 5e3+5;
const int maxn = 2e4+5;
const int INF = 0x3f3f3f3f;
struct line{
    int l,r;
    int h;
    int flag;
}e[maxn<<2];
struct node{
    int l,r;
    int s;
    int li,ri;
    int len;
    int num;
}a[maxn<<2];
int total;
int n;
bool cmp(line p,line q){
    return p.h < q.h;
}
void build(int l,int r,int rt){
    a[rt].l = l;
    a[rt].r = r;
    a[rt].s = 0;
    a[rt].li = a[rt].ri = 0;
    a[rt].len = 0;
    a[rt].num = 0;
    if(l == r)return ;
    int m = (l+r)>>1;
    build(lson);
    build(rson);
}
void PushUp(int rt){
    if(a[rt].s){
        a[rt].ri = a[rt].li =1;
        a[rt].len = a[rt].r - a[rt].l+1;
        a[rt].num =1;
    }else if(a[rt].l == a[rt].r){
        a[rt].ri = a[rt].li = 0;
        a[rt].len = 0;
        a[rt].num = 0;
    }else{
        a[rt].li = a[rt<<1].li;
        a[rt].ri = a[rt<<1|1].ri;
        a[rt].len = a[rt<<1].len + a[rt<<1|1].len;
        a[rt].num = a[rt<<1].num + a[rt<<1|1].num - (a[rt<<1].ri&a[rt<<1|1].li);
    }
}
void update(int L,int R,int flag,int rt){
    if(L<=a[rt].l && a[rt].r <= R){
        a[rt].s += flag;
        PushUp(rt);
        return;
    }
    int m = (a[rt].l+a[rt].r)/2;
    if(L<=m) update(L,R,flag,rt<<1);
    if(R>m) update(L,R,flag,rt<<1|1);
    PushUp(rt);
}
int ab(int x){
    if(x<0) return -x;
    else return x;
}
int main(){
    while(~scanf("%d",&n)){
        int mm=-INF,mim = INF;
        total = 0;
        int x1,x2,y1,y2;
        for(int i=0;i<n;i++){
            scanf("%d %d %d %d",&x1,&y1,&x2,&y2);
            e[total].l = e[total+1].l = x1;
            e[total].r = e[total+1].r = x2;
            e[total].h = y1;
            e[total+1].h = y2;
            e[total].flag = 1;
            e[total+1].flag = -1;
            mm = max(mm,max(x1,x2));
            mim = min(mim,min(x1,x2));
            total+=2;
        }
        sort(e,e+total,cmp);
        build(mim,mm-1,1);
        int ans = 0;
        int last = 0;
        for(int i=0;i<total;i++){
            update(e[i].l,e[i].r-1,e[i].flag,1);
            int res = a[1].len;
            ans+= ab(res-last);
            ans+=(e[i+1].h - e[i].h)*a[1].num*2;
            last = res;
        }
        printf("%d\n",ans);
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值