题目大意:给你N个矩形,问这N个矩形的轮廓面积

解题思路:线段树 扫描线的裸题了,具体可以百度一下,这边就没有那么多的图文解说了。。。

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 110 << 3;

struct segment{
    double l, r, h;
    int f;
}S[N];

int cnt[N];
double len[N], pos[N];
int n, snum;

bool cmp(struct segment &a, struct segment &b) {
    return a.h < b.h;
}

void build(int u, int l, int r) {
    len[u] = 0; cnt[u] = 0;
    if (l == r) return ;
    int mid = (l + r) >> 1;
    build(u << 1, l, mid);
    build(u << 1 | 1, mid + 1, r);

}

void get_len(int u, int l, int r) {
    if (cnt[u]) len[u] = pos[r + 1] - pos[l];
    else if (l == r) len[u] = 0;
    else len[u] = len[u << 1] + len[u << 1 | 1];
}

void Modify(int u, int l, int r, int L, int R, int val) {
    if (l == L && r == R) {
        cnt[u] += val;
        get_len(u, l, r);
        return ;
    }
    int mid = (l + r) >> 1;
    if (R <= mid) Modify(u << 1, l, mid, L, R, val);
    else if (L > mid) Modify(u << 1 | 1, mid + 1, r, L, R, val);
    else {
        Modify(u << 1, l, mid, L, mid, val);
        Modify(u << 1 | 1, mid + 1, r, mid + 1, R, val);
    }
    get_len(u, l, r);
}

int find(double val, int l, int r) {
    while(l <= r) {
        int mid = (l + r) >> 1;
        if (pos[mid] == val) return mid;
        else if (pos[mid] > val) r = mid - 1;
        else l = mid + 1;
    }
    return -1;
}

int main() {
    int cas = 1;
    while (scanf("%d", &n) && n) {
        double x1, x2, y1, y2;
        snum = 1;
        for (int i = 1; i <= n; i++) {
            scanf("%lf%lf%lf%lf", &x1, &y1, &x2, &y2);
            S[snum].l = S[snum + 1].l = x1;
            S[snum].r = S[snum + 1].r = x2;
            S[snum].h = y1; S[snum + 1].h = y2;
            S[snum].f = 1; S[snum + 1].f = -1;  
            pos[snum] = x1; pos[snum + 1] = x2;
            snum += 2;
        }
        sort(S + 1, S + snum , cmp);
        sort(pos + 1, pos + snum);
        int m = 1;
        for (int i = 2; i < snum; i++)
            if (pos[i] != pos[i - 1]) 
                pos[++m] = pos[i];
        build(1, 1, m);
        double ans = 0;
        for (int i = 1; i < snum; i++) {
            int l = find(S[i].l, 1, m);
            int r = find(S[i].r, 1, m) - 1;
            Modify(1, 1, m, l, r, S[i].f);
            ans += (S[i + 1].h - S[i].h) * len[1];
        }
        printf("Test case #%d\n", cas++);
        printf("Total explored area: %.2f\n\n", ans);
    }

    return 0;
}