• [Luogu] 被污染的河流


    https://www.luogu.org/problemnew/show/P3875

    线段树扫描线求矩形面积并

    扫描线的线段树有点奇怪,修改的标记不会下传,标记的意义是当前区间被完整地覆盖了多少次,我们可以根据这个标记来求这个区间覆盖了至少一次的长度和至少两次的长度

    :数组大小

    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    
    #define gc getchar()
    
    using std:: sort;
    using std:: cout;
    using std:: min;
    using std:: max;
    const int N = 10100;
    
    int n, js;
    int X[N << 2], W[N << 4], F[N << 4];
    struct Node {int x_1, x_2, h, how;} lp[N << 1];
    
    inline int read() {
        int x = 0; char c = gc;
        while(c < '0' || c > '9') c = gc;
        while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = gc;
        return x;
    }
    
    inline void Add(int _x_1, int _y_1, int _x_2, int _y_2) {
        if(_y_1 == _y_2) {
            int _1 = _x_1, _2 = _x_2;
            _x_1 = min(_1, _2); _x_2 = max(_1, _2);
            lp[++ js].x_1 = _x_1; lp[js].x_2 = _x_2; lp[js].h = _y_1 - 1; lp[js].how = 1; X[js] = _x_1;
            lp[++ js].x_1 = _x_1; lp[js].x_2 = _x_2; lp[js].h = _y_1 + 1; lp[js].how = -1; X[js] = _x_2;
        } else {
            int _1 = _y_1, _2 = _y_2;
            _y_1 = min(_1, _2); _y_2 = max(_1, _2);
            lp[++ js].x_1 = _x_1 - 1; lp[js].x_2 = _x_1 + 1; lp[js].h = _y_1; lp[js].how = 1; X[js] = _x_1 - 1;
            lp[++ js].x_1 = _x_1 - 1; lp[js].x_2 = _x_1 + 1; lp[js].h = _y_2; lp[js].how = -1; X[js] = _x_1 + 1;
        }
    }
    
    inline bool cmp(Node a, Node b) {return a.h < b.h;}
    
    int Find(int num, int r_) {
        int L = 1, R = r_, ret;
        while(L <= R) {
            int Mid = (L + R) >> 1;
            if(X[Mid] <= num) L = Mid + 1, ret = Mid;
            else R = Mid - 1;
        }
        return ret;
    }
    
    #define lson jd << 1
    #define rson jd << 1 | 1
    
    void Pushup(int jd, int l, int r) {
        if(F[jd]) W[jd] = X[r + 1] - X[l];
        else if(l == r) W[jd] = 0;
        else W[jd] = W[lson] + W[rson];
    }
    
    void Sec_G(int l, int r, int jd, int x, int y, int how) {
        if(x <= l && r <= y) {F[jd] += how; Pushup(jd, l, r); return ;}
        int mid = (l + r) >> 1;
        if(x <= mid) Sec_G(l, mid, lson, x, y, how);
        if(y > mid)  Sec_G(mid + 1, r, rson, x, y, how);
        Pushup(jd, l, r);
    }
    
    int main() {
        n = read();
        for(int i = 1; i <= n; i ++) {
            int x_1 = read(), y_1 = read(), x_2 = read(), y_2 = read();
            Add(x_1, y_1, x_2, y_2);
        }
        sort(X + 1, X + js + 1);
        sort(lp + 1, lp + js + 1, cmp);
        int k = 1;
        for(int i = 2; i <= js; i ++) if(X[i] != X[i + 1]) X[++ k] = X[i];
        long long Answer = 0;
        for(int i = 1; i < js; i ++) {
            int l = Find(lp[i].x_1, k), r = Find(lp[i].x_2, k) - 1;
            Sec_G(1, k - 1, 1, l, r, lp[i].how);
            Answer += W[1] * (lp[i + 1].h - lp[i].h);
        }
        cout << Answer;
        return 0;
    }
  • 相关阅读:
    openjudge-NOI 2.6-1996 登山
    openjudge-NOI 2.6-1944 吃糖果
    openjudge-NOI 2.6-1808 公共子序列
    openjudge-NOI 2.6-1775 采药
    openjudge-NOI 2.6-1768 最大子矩阵
    openjudge-NOI 2.6-1759 最长上升子序列
    tyvj P1050 最长公共子序列
    动态规划-最长公共子序列
    动态规划-最长上升子序列
    HDU 1811 Rank of Tetris
  • 原文地址:https://www.cnblogs.com/shandongs1/p/8543201.html
Copyright © 2020-2023  润新知