扫描线线段树模板

#include<cstring>
#include<algorithm>
#include<cstdio>
#include<cstdlib>
#define lson rt<<1
#define rson rt<<1|1
#define fmid (tree[rt].l + tree[rt].r)>>1

using namespace std;
const int maxn = 1e6 + 9;
struct node
{
    int l, r;
    int s;
    long long len, len1;
};

struct edge
{
    long long l, r, h;
    int f;
};
edge line[maxn<<1];
node tree[maxn<<3];
long long x[maxn<<1];
bool cmp(edge a, edge b)
{
    return a.h < b.h;
}

void build(int l, int r, int rt)
{
    tree[rt].l = l, tree[rt].r = r;
    tree[rt].len1 = 0, tree[rt].len = 0;
    tree[rt].s = 0;
    if(l == r)
        return;
    int mid = fmid;
    build(l, mid, lson);
    build(mid + 1, r, rson);
}

void pushup(int rt)
{
    if(tree[rt].s > 1)
    {
        tree[rt].len1 = x[tree[rt].r + 1] - x[tree[rt].l];
    }
    else if(tree[rt].s == 1)
    {
        tree[rt].len = x[tree[rt].r + 1] - x[tree[rt].l];
        if(tree[rt].l == tree[rt].r) tree[rt].len1 = 0;
        else
        {
            tree[rt].len1 = tree[lson].len + tree[rson].len;
        }
    }
    else
    {
        if(tree[rt].l == tree[rt].r)
        {
            tree[rt].len = tree[rt].len1 = 0;
        }
        else
        {
            tree[rt].len = tree[lson].len + tree[rson].len;
            tree[rt].len1 = tree[lson].len1 + tree[rson].len1;
        }
    }
}
void update(int l, int r, int f, int rt)
{
    if(tree[rt].l == l && tree[rt].r == r)
    {
        tree[rt].s += f;
        pushup(rt);
        return;
    }
    int mid = fmid;
    if(r <= mid) update(l, r, f, lson);
    else if(l > mid) update(l, r, f, rson);
    else
    {
        update(l, mid, f, lson);
        update(mid + 1, r, f, rson);
    }
    pushup(rt);
}

int main()
{
    int n;
    scanf("%d", &n);
    memset(line, 0, sizeof(line));
    int tot = 0;
    for(int i = 0; i < n; i++)
    {
        long long x1, x2, y1, y2;
        scanf("%lld%lld%lld%lld", &x1, &y1, &x2, &y2);
        edge &t1 = line[tot];
        edge &t2 = line[tot + 1];
        t1.l = t2.l = x1;
        t1.r = t2.r = x2;
        t1.h = y1, t1.f = 1;
        t2.h = y2, t2.f = -1;
        x[tot] = x1, x[tot + 1] = x2;
        tot += 2;
    }
    sort(line, line + tot, cmp);
    sort(x, x + tot);
    int cnt = unique(x, x + tot) - x;
    build(0, cnt - 1, 1);
    long long ans = 0;
    for(int i = 0; i < tot; i++)
    {
        int l = lower_bound(x, x + cnt, line[i].l) - x;
        int r = lower_bound(x, x + cnt, line[i].r) - x - 1;
        update(l, r, line[i].f, 1);
        ans += (line[i + 1].h - line[i].h) * tree[1].len; // 交集和并集改动len 和len1
    }
    printf("%lld\n", (long long)ans);
    return 0;
}

发布了40 篇原创文章 · 获赞 13 · 访问量 851

猜你喜欢

转载自blog.csdn.net/weixin_43891021/article/details/102666492
今日推荐