zoukankan      html  css  js  c++  java
  • [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;
    }
  • 相关阅读:
    Apache Flink 1.12.1发布
    flink 修改web页面刷新时间
    flink 支持的sql 方言
    flink sql 读取hive 表报错
    Typora配置正文、目录、侧边大纲中的标题自动编号
    滴滴开源Logi-KafkaManager 一站式Kafka监控与管控平台
    建立 nfs 服务器
    Linux 设备驱动的第一个例子 。
    备份.vimrc
    shell编程实例
  • 原文地址:https://www.cnblogs.com/shandongs1/p/8543201.html
Copyright © 2011-2022 走看看