cf610D 面积并

题目链接
题意:
给你n个线段,让你求这n个线段形成新的图形的周长。
思路:
把一个(a,b) (c,d) (第一个点在第二个点左或下),看成左下点(a-1,b-1),右上点(c,d)的矩形,然后求面积并即可。
基本跟面积并模板题一样,就建边的时候多写三行就行。

const int N=2*(int)1e5+100;
int n,v[N],maxNode;
struct LI{
    i64 x;
    int y11,y22,state;
    LI(i64 _x=0, int _y11=0, int _y22=0, int _state=0){
        x=_x;
        y11=_y11;
        y22=_y22;
        state=_state;
    }
    bool operator < (const LI &rhs) const{
        return x<rhs.x;
    }
}l[N];
struct SE{
    int l,r,cover;
    i64 len;
}seg[N*8];
void pushUp(int node){
    if(seg[node].cover>0) seg[node].len=seg[node].r-seg[node].l;
    else seg[node].len=seg[node<<1].len+seg[node<<1|1].len;
}
void build(int node, int l, int r){
    uax(maxNode,node);
    seg[node].l=v[l]; seg[node].r=v[r];
    seg[node].cover=seg[node].len=0;
    if(r-l<=1) return;
    int mid=(l+r)>>1;
    build(node<<1,l,mid);
    build(node<<1|1,mid,r);
}
void update(int node, int ul, int ur, int nowState){
    if(node>maxNode) return;
    int l=seg[node].l,r=seg[node].r;
    if(ul<=l && r<=ur){
        seg[node].cover+=nowState;
        pushUp(node);
        return;
    }
    if(ul<seg[node<<1].r) update(node<<1,ul,ur,nowState);
    if(ur>seg[node<<1|1].l) update(node<<1|1,ul,ur,nowState);
    pushUp(node);
}
int main() {
    maxNode=-1;
    scanf("%d",&n);
    for(int i=1; i<=n; ++i){
        i64 a,c;
        int b,d;
        scanf("%lld%d%lld%d",&a,&b,&c,&d);
        if(a>c) swap(a,c); //就多写这三行..
        if(b>d) swap(b,d); //
        --a; --b;          //
        l[i]=LI(a,b,d,1);
        l[i+n]=LI(c,b,d,-1);
        v[i]=b;
        v[i+n]=d;
    }
    sort(l+1,l+1+2*n);
    sort(v+1,v+1+2*n);
    build(1,1,2*n);
    i64 ans=0;
    for(int i=1; i<=2*n; ++i){
        ans+=seg[1].len*(l[i].x-l[i-1].x);
        update(1,l[i].y11,l[i].y22,l[i].state);
    }
    printf("%lld\n",ans);
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值