扫描线

建议移步fsy的博客
讲的比较清楚
注意判一下边界条件
丢个板

#include<bits/stdc++.h>
#define int long long
#define N (300000 + 10)
using namespace std;

inline void read(int &cnt) {
    cnt = 0;
    int f = 1; char c = getchar();
    while (!isdigit(c)) {if (c == '-') f = -f; c = getchar();}
    while (isdigit(c)) {cnt = (cnt << 3) + (cnt << 1) + (c ^ 48); c = getchar();}
    cnt *= f;
}

int n, tot = 0, ans = 0;
int a, b, c, d, cnt;
int Y[N << 1];
struct Line {
    int x, Y1, Y2;
    int k;
}seg[N << 1];
bool cmp(Line a, Line b) {return a.x == b.x ? a.Y1 < b.Y1 : a.x < b.x;}

struct node {
    int l, r;
    int cnt, len;
    #define l(p) tree[p].l
    #define r(p) tree[p].r
    #define cnt(p) tree[p].cnt
    #define len(p) tree[p].len
}tree[N << 2];

void pushup(int p) {
    if (cnt(p) > 0) len(p) = Y[r(p)] - Y[l(p)];
    else len(p) = len(p << 1) + len(p << 1 | 1);
}

void build(int p, int l, int r) {
//  cout<<p<<endl;
    l(p) = l, r(p) = r;
    if (l == r - 1) {len(p) = cnt(p) = 0; return;}
    int mid = (l + r + 1) >> 1;
    build(p << 1, l, mid);
    build(p << 1 | 1, mid, r);
//  pushup(p);
}

void modify(int p, int l, int r, int k) {
    if (l <= Y[l(p)] && r >= Y[r(p)]) cnt(p) += k;
    else {  
        int mid = (l(p) + r(p) + 1) >> 1;
        if (l < Y[mid]) modify(p << 1, l, r, k);
        if (r > Y[mid]) modify(p << 1 | 1, l, r, k);
    }
        pushup(p);
}

signed main() {
    read(n);
    for (register int i = 1; i <= n; ++i) {
        read(a), read(b), read(c), read(d);
        seg[++cnt].x = a, seg[cnt].Y1 = b, seg[cnt].Y2 = d, seg[cnt].k = 1, Y[cnt] = b;
        seg[++cnt].x = c, seg[cnt].Y1 = b, seg[cnt].Y2 = d, seg[cnt].k = -1, Y[cnt] = d;
    }
    sort(seg + 1, seg + cnt + 1, cmp);
    sort (Y + 1, Y + cnt + 1);
    tot = unique(Y + 1, Y + cnt + 1) - Y - 1;
    build(1, 1, tot);
    for (register int i = 1; i <= cnt - 1; ++i) {
        modify(1, seg[i].Y1, seg[i].Y2, seg[i].k);
        ans += (seg[i + 1].x - seg[i].x) * len(1);
//      cout<<ans<<endl;
    } printf("%lld", ans);
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值