• [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;
    }
  • 相关阅读:
    JavaScript 本地对象、内置对象、宿主对象
    数据交换格式
    网页设计之内容、结构、表现分离
    Web前端浏览器兼容初探
    javascript call()与apply()
    天气API
    display:inline,display:inline-block,display:block 区别
    javascript sort()与reverse()
    The Primo ScholarRank Technology: Bringing the Most Relevant Results to the Top of the List
    IOS ——OC—— NSMutableDictionary的使用总结
  • 原文地址:https://www.cnblogs.com/shandongs1/p/8543201.html
Copyright © 2020-2023  润新知