• 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;
    }
  • 相关阅读:
    看到差距了,受打击
    数码相机选购指南(应小麻之作)
    sorry
    ACM集训第一天
    没事了,放心了,回到自己,又有些失落
    黑暗世界的一线光明

    无忧无虑的睡去,是一种奢华的享受(新)
    一些废话
    对事不对人
  • 原文地址:https://www.cnblogs.com/Rosebud/p/9071648.html
Copyright © 2020-2023  润新知