zoukankan      html  css  js  c++  java
  • hdu 5091 Beam Cannon(扫描线段树)

    题目链接:hdu 5091 Beam Cannon

    题目大意:给定N个点,如今要有一个WH的矩形,问说最多能圈住多少个点。

    解题思路:线段的扫描线,如果有点(x,y),那么(x,y)~(x+W,y+H)形成的矩形,以框的右下角落的位置是能够圈住(x,y)

    点,所以N个点即为N个矩形,求覆盖的最大次数,扫描线裸题。

    #include <cstdio>
    #include <cstring>
    #include <vector>
    #include <algorithm>
    
    using namespace std;
    const int maxn = 40005;
    const int bw = 20000;
    
    #define lson(x) ((x)<<1)
    #define rson(x) (((x)<<1)|1)
    int lc[maxn << 2], rc[maxn << 2], ad[maxn << 2], nd[maxn << 2];
    
    inline void pushup(int u) {
        nd[u] = max(nd[lson(u)], + nd[rson(u)]) + ad[u];
    }
    
    inline void maintain(int u, int v) {
        ad[u] += v;
        nd[u] += v;
    }
    
    void build(int u, int l, int r) {
        lc[u] = l;
        rc[u] = r;
        ad[u] = nd[u] = 0;
    
        if (l == r)
            return;
        int mid = (l + r) >> 1;
        build(lson(u), l, mid);
        build(rson(u), mid + 1, r);
        pushup(u);
    }
    
    void modify(int u, int l, int r, int v) {
        if (l <= lc[u] && rc[u] <= r) {
            maintain(u, v);
            return;
        }
    
        int mid = (lc[u] + rc[u]) >> 1;
        if (l <= mid)
            modify(lson(u), l, r, v);
        if (r > mid)
            modify(rson(u), l, r, v);
        pushup(u);
    }
    
    int query(int u, int l, int r) {
        if (l <= lc[u] && rc[u] <= r)
            return nd[u];
    
        int mid = (lc[u] + rc[u]) >> 1, ret = 0; 
        if (l <= mid)
            ret = max(ret, query(lson(u), l, r));
        if (r > mid)
            ret = max(ret, query(rson(u), l, r));
        pushup(u);
        return ret;
    }
    
    struct Seg {
        int x, l, r, w;
        Seg(int x = 0, int l = 0, int r = 0, int w = 0) {
            this->x = x;
            this->l = l;
            this->r = r;
            this->w = w;
        }
    };
    vector<Seg> G;
    
    inline bool cmp (const Seg& a, const Seg& b) {
        if (a.x != b.x)
            return a.x < b.x;
        return a.w < b.w;
    }
    
    int N, W, H;
    
    void init () {
        int x, y;
        G.clear();
        scanf("%d%d", &W, &H);
        for (int i = 0; i < N; i++) {
            scanf("%d%d", &x, &y);
            G.push_back(Seg(x, y + bw, min(bw, y + H) + bw, 1));
            G.push_back(Seg(x + W + 1, y + bw, min(bw, y + H) + bw, -1));
        }
        build(1, 0, bw * 2);
        sort(G.begin(), G.end(), cmp);
    }
    
    int main () {
    
        while (scanf("%d", &N) == 1 && N != -1) {
            init();
            int ans = 0;
            for (int i = 0; i < G.size(); i++) {
                modify(1, G[i].l, G[i].r, G[i].w);
                ans = max(ans, nd[1]);
            }
            printf("%d
    ", ans);
        }
        return 0;
    }

    版权声明:本文博主原创文章,博客,未经同意不得转载。

  • 相关阅读:
    001.云桌面整体解决方案实施
    Netty基础招式——ChannelHandler的最佳实践
    架构设计之数据分片
    Go是一门什么样的语言?
    Jenkins汉化配置
    Window安装构建神器Jenkins
    uni-app&H5&Android混合开发三 || uni-app调用Android原生方法的三种方式
    如何使用Hugging Face中的datasets
    关于torch.nn.LSTM()的输入和输出
    pytorch中的nn.CrossEntropyLoss()计算原理
  • 原文地址:https://www.cnblogs.com/zfyouxi/p/4854528.html
Copyright © 2011-2022 走看看