HDU 1542 矩形面积并

推荐阅读这篇文章

这里仅根据上述文章进行一些补充。主要是注意这里线段树点的意义变成了“边”。比如+-----+-----+,看作3个点abc和两条边e1和e2,那么线段树中点a代表e1,点b代表e2。那么我们在算cover(想象成染黑)的时候,将(a,b,c)这一段染黑的时候,其实只需要染线段树中的a和b点即可!这里解释了,为什么染[l,r]的时候,实际上染的是[l, r - 1]。

但是,push_up的时候,线段树中的l,r对应实际点的l和r-1,所以要补上个1,这里解释的是为什么if(cover[rt]) seg[rt] = x[r + 1] - x[l]; 

最终代码:

#include <bits/stdc++.h>
using namespace std;

const int maxN=2e2+5;
int N, M, K, cas;

#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define rch rt<<1
#define lch rt<<1|1

int cov[maxN<<2]; 
double T[maxN<<2], x[maxN];
vector<double> v;

struct Line {
    double l, r, h; int fg;
    Line(double a=0, double b=0, double c=0, int d=1):
        l(a), r(b), h(c), fg(d){}
    bool operator < (const Line &s2) const {return h < s2.h;}
};
vector<Line> ln;

void push_up(int l, int r, int rt) {
    if (cov[rt]) T[rt] = v[r + 1] - v[l];
    else if (l == r) T[rt] = 0;
    else  T[rt] = T[lch] + T[rch];
}
void update(int L, int R, int f, int l, int r, int rt) {
    if (L <= l && r <= R) {
        cov[rt] += f;
        push_up(l, r, rt);
        return;
    }
    int m = (l + r) / 2;
    if (L <= m) update(L, R, f, lson);
    if (R > m) update(L, R, f, rson);
    push_up(l, r, rt);
}
int main () {
#ifndef ONLINE_JUDGE
    freopen("data.in", "r", stdin);
#endif

    cas = 1;
    while (~scanf("%d", &N) && N) {
        v.clear(), ln.clear();
        memset(cov, 0, sizeof cov), memset(T, 0, sizeof T);

        double x1, y1, x2, y2;
        for (int i = 0; i < N; ++i) {
            scanf("%lf%lf%lf%lf", &x1, &y1, &x2, &y2);
            v.push_back(x1), v.push_back(x2);
            ln.push_back(Line(x1, x2, y1, 1));
            ln.push_back(Line(x1, x2, y2, -1));
        }
        sort(v.begin(), v.end()), sort(ln.begin(), ln.end());
        v.erase(unique(v.begin(), v.end()), v.end());

        double ans = 0;
        for (int i = 0; i < (int)ln.size() - 1; ++i) {
            int L = lower_bound(v.begin(), v.end(), ln[i].l) - v.begin();
            int R = lower_bound(v.begin(), v.end(), ln[i].r) - v.begin();
            if (R > L)
                update(L, R - 1, ln[i].fg, 0, v.size() - 1, 1);
            ans += T[1] * (ln[i + 1].h - ln[i].h);
        }
        printf("Test case #%d
Total explored area: %.2lf

", cas++, ans);
    }
    return 0;
}
原文地址:https://www.cnblogs.com/Rosebud/p/9071648.html