P5490 【模板】扫描线 面积并

#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
typedef long long ll;
const int maxn = 1000000 + 10;
struct Line
{
    ll L, R, h;
    int c; // 标记这条这条边为入边还是出边
    Line() {}
    Line(ll a, ll b, ll c, int d) : L(a), R(b), h(c), c(d) {}
    bool operator<(const Line &a) const
    {
        return h < a.h;
    }
} line[maxn << 1];
struct Seg_Tree
{
    int L, R; // 这个节点管理的左x端点和右x端 管理的是区间端点
    int sum;  // 覆盖次数
    ll len;   // 区间被截取的长度
} tree[maxn << 2];
int n, X[maxn << 1];
void pushup(int node)
{
    int l = tree[node].L;
    int r = tree[node].R;
    if (tree[node].sum)
        tree[node].len = X[r + 1] - X[l];
    else
        tree[node].len = tree[node << 1].len + tree[node << 1 | 1].len;
}
void Creat(int node, int L, int R)
{
    tree[node].L = L;
    tree[node].R = R;
    tree[node].len = 0;
    tree[node].sum = 0;
    if (L == R)
        return;
    int mid = (L + R) >> 1;
    Creat(node << 1, L, mid);
    Creat(node << 1 | 1, mid + 1, R);
    return;
}
void update(int node, ll L, ll R, int c)
{
    int l = tree[node].L; // 当前节点管辖区间左端点
    int r = tree[node].R; // 当前节点管辖区间右端点
    if (X[r + 1] <= L || R <= X[l])
    {
        return;
    }
    if (L <= X[l] && X[r + 1] <= R)
    {
        tree[node].sum += c;
        pushup(node);
        return;
    }
    update(node << 1, L, R, c);
    update(node << 1 | 1, L, R, c);
    pushup(node);
}
int main()
{
#ifdef ONLINE_JUDGE
#else
    freopen("in.txt", "r", stdin);
    freopen("out.txt", "w", stdout);
#endif
    ll x1, y1, x2, y2;
    scanf("%d", &n);
    for (int i = 1; i <= n; i++)
    {
        scanf("%lld %lld %lld %lld", &x1, &y1, &x2, &y2);
        line[i * 2 - 1] = Line(x1, x2, y1, 1);
        line[i * 2] = Line(x1, x2, y2, -1);
        X[i * 2 - 1] = x1;
        X[i * 2] = x2;
    }
    n <<= 1;
    sort(line + 1, line + n + 1);
    sort(X + 1, X + n + 1);
    int tot = unique(X + 1, X + n + 1) - X - 1;
    cout << tot << endl;
    Creat(1, 1, tot - 1);
    ll ans = 0;
    for (int i = 1; i < n; i++)
    {
        update(1, line[i].L, line[i].R, line[i].c);
        ans += tree[1].len * (line[i + 1].h - line[i].h);
    }
    printf("%lld", ans);
    return 0;
}
发布了59 篇原创文章 · 获赞 22 · 访问量 3841

猜你喜欢

转载自blog.csdn.net/qq_44115065/article/details/103994557