zoukankan      html  css  js  c++  java
  • [BZOJ4237] 稻草人

    [BZOJ4237] 稻草人

    题目大意:给出一个平面坐标系,(n)个点((x_i,y_i)),求以任一个点为左下角,另一个点为右上角,最多能组成多少个矩形中没有其他点的矩形.((x_i)互不相同,(y_i)互不相同)

    Solution

    将区间二分后分别处理,并将两个区间共同组成的答案统计.

    1. 按照(x)从小到大对整个区间排序

    2. 将区间分为([l,mid])([mid+1, r]),先求解([l,mid])

    3. 两段区间分别按照(y)从大到小排序

      得到((2,2), (0,0))((3,4),(4,3))

    4. 建立两个单调栈,(lsta)(x)单调递减,(rsta)(x)单调递增,先加入左边的元素,来统计有多少的右边元素可以构成矩形

      左栈

    5. 在左栈里面,(A)先加入的,如果(B)加入后(x)还变大了,说明(A)根本不会影响到(B)

      右栈

    6. 在右栈里,(A)先加入,如果(B)加入后(x)还变小了,说明(A)根本就没有用了,统计不到答案了

    7. 统计完答案后,用(x)排序,消除影响,处理([mid+1,r])

    Code

    #include <iostream>
    #include <cstdio>
    #include <algorithm>
        
    using std::sort;
        
    const int N = 2e5 + 10;
        
    struct  Node{
        int x, y;
    }a[N], l_sta[N], r_sta[N];
        
    int n;
    long long ans;
        
    inline int read(){
        int x = 0, f = 1;
        char ch = getchar();
        while(ch < '0' || ch > '9'){
            if(ch == '-')
                f = -1;
            ch = getchar();
        }
        while(ch >= '0' && ch <= '9'){
            x = (x << 3) + (x << 1) + (ch ^ 48);
            ch = getchar();
        }
        return x * f;
    }
        
    inline bool cmp1(Node a, Node b){
        return a.x < b.x;
    }
        
    inline bool cmp2(Node a, Node b){
        return a.y > b.y;
    }
        
    inline int find(int x, int qwq){
        int l = 1, r = qwq, mid;
        while(l <= r){
            mid = l + ((r - l) >> 1);
            if(r_sta[mid].y <= x){
                r = mid - 1;
            }
            else {
                l = mid + 1;
            }
        }
        return r;
    }
        
    void solve(int l, int r){
        if(l >= r) return;
        int mid = l + ((r - l) >> 1);
        solve(l, mid);
        sort(a + l, a + mid + 1, cmp2);
        sort(a + mid + 1, a + r + 1, cmp2);
        int r_top = 0, l_top = 0, p = mid + 1, ll, rr;
        l_sta[0].y = r_sta[0].y = 2100000000;
        for(int i = l; i <= mid; ++i){//l写成1也是醉了
            while(p <= r && a[p].y > a[i].y){
                while(r_top && a[p].x < r_sta[r_top].x){
                    r_top--;
                }
                r_sta[++r_top] = a[p];
                p++;
            }
            while(l_top && a[i].x > l_sta[l_top].x){
                l_top--;
            }
            l_sta[++l_top] = a[i];
            ll = find(l_sta[l_top - 1].y, r_top) + 1;
            rr = find(l_sta[l_top].y, r_top);
            if(rr >= ll)
                ans += (long long)(rr - ll + 1);
             
        }
        sort(a + l, a + mid + 1, cmp1);
        sort(a + mid + 1, a + r + 1, cmp1);
        solve(mid + 1, r);
    }
        
    int main(){
        scanf("%d", &n);
        for(int i = 1; i <= n ;++i){
            scanf("%d %d", &a[i].x, &a[i].y);
        }
        sort(a + 1, a + n + 1, cmp1);
        solve(1, n);
        printf("%lld
    ", ans);
        return 0;
    }
    
  • 相关阅读:
    kuberdm安装
    docker网络
    docker安装及基本使用
    慢日志
    mysql-5.7主从复制
    MySQL-5.6主从复制
    MySQL索引原理
    Kubernetes的kubeadm项目安装部署
    十六、kubernetes之安全实验案例
    十五、Kubernetes之安全配置
  • 原文地址:https://www.cnblogs.com/LMSH7/p/9516858.html
Copyright © 2011-2022 走看看