hdu 5091 Beam Cannon(线段树扫描线)

题目链接:hdu 5091 Beam Cannon

题目大意:给定N个点,现在要有一个W?H的矩形,问说最多能圈住多少个点。

解题思路:线段的扫描线,假设有点(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\n", ans);
    }
    return 0;
}
时间: 2024-11-29 01:59:05

hdu 5091 Beam Cannon(线段树扫描线)的相关文章

[POI 2001+2014acm上海邀请赛]Gold Mine/Beam Cannon 线段树+扫描线

Description Byteman, one of the most deserving employee of The Goldmine of Byteland, is about to retire by the end of the year. The Goldmine management would like to reward him in acknowledgment of his conscientious work. As a reward Byteman may rece

HDU5091 Beam Cannon(线段树扫描线)

#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&

hdu 5091 Beam Cannon 离散化+扫描线+线段树

Beam Cannon Time Limit: 3000/1500 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 551    Accepted Submission(s): 207 Problem Description Recently, the γ galaxies broke out Star Wars. Each planet is warring for resou

hdu 5091 Beam Cannon(线段树+扫描线+离散化)

Beam Cannon Time Limit: 3000/1500 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 457    Accepted Submission(s): 175 Problem Description Recently, the γ galaxies broke out Star Wars. Each planet is warring for resou

hdu 5091 Beam Cannon

题目大意: 有n个点(n<=10000),点的坐标绝对值不超过20000,然后问你用一个w*h(1<=w,h<=40000)的矩形,矩形的边平行于坐标轴,最多能盖住多少个点. 刘汝佳黑书上有原题 下面这份代码是加了离散化的,用垂直于x轴的直线去扫描,在y轴上建立线段树,所以对于每一个点(x,y),赋予权值1,,然后增加一个新的负点(x+w,y),赋予权值-1.当扫描线扫过每一个点,用该点的权值去区间更新线段树.维护每个区间的sum值,因为是区间更新,所以还要打个lazy标记. 1 #in

HDU 3265 Posters ——(线段树+扫描线)

第一次做扫描线,然后使我对线段树的理解发生了动摇= =..这个pushup写的有点神奇.代码如下: 1 #include <stdio.h> 2 #include <algorithm> 3 #include <string.h> 4 #define t_mid (l+r>>1) 5 #define ls (o<<1) 6 #define rs (o<<1|1) 7 #define lson ls,l,t_mid 8 #define

HDU 1542 Atlantis(线段树扫描线+离散化求面积的并)

Atlantis Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 11551    Accepted Submission(s): 4906 Problem Description There are several ancient Greek texts that contain descriptions of the fabled

HDU 1828 Picture(线段树扫描线求周长)

Picture Time Limit: 6000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 4475    Accepted Submission(s): 2207 Problem Description A number of rectangular posters, photographs and other pictures of the same shap

Hdu 4419 Colourful Rectangle(线段树扫描线)

题目大意: 给出多个不同颜色的矩形,求最后覆盖的颜色的面积. 思路分析: 我是自己手动暴力枚举. 比赛的时候漏了一种情况. RGB 可以从 RG+RB组合来(只是举例,就是说可以从两种颜色组合而来). 然后就只需要维护所有的颜色 用扫描线来判断. #include <iostream> #include <cstdio> #include <algorithm> #include <cstring> #define MAXN 42222 using name