hdu 5091 Beam Cannon(线段树)

来源:互联网 发布:java 1.7 32位官网 编辑:程序博客网 时间:2024/04/29 18:45

hdu 5091 Beam Cannon

实际上题目约等于在一条横坐标轴下有一系列的点,求用一个定长(L)的线段能覆盖的最大点数,且点可动态增减。
对于可能覆盖的每个点x,线段的中心位置可以用一个区间表示[x-L/2,x+L/2]。那么最终结果就等于某一范围被重叠的最多次次数。由此再推广到二维坐标系
#include <stdio.h>#include <vector>#include <string>#include <algorithm>#include <queue>#include <cstring>#include <map>#include <set>#include <iostream>#include <cmath>using namespace std;typedef long long LL;#define ll (rot<<1)#define rr (ll | 1)#define mid mm = (l+r)>>1#define lson l,mm,ll#define rson mm+1,r,rrconst int MAXN = 50005;int num[MAXN<<2], ad[MAXN<<2];struct _node{    int x, y;    int l, r;    bool operator < (const _node & a) const    {        if (y != a.y) return y < a.y;        return x < a.x;    }}da[MAXN];int n, w, h;int cx[MAXN], cn;void build(int l, int r, int rot){    num[rot] = 0;    ad[rot] = 0;    if (l == r) return ;    int mid;    build(lson);    build(rson);}void pushup(int rot){    num[rot] = max(num[ll], num[rr]);}void pushdown(int rot){    if (!ad[rot]) return;    num[ll] += ad[rot];    ad[ll] += ad[rot];    num[rr] += ad[rot];    ad[rr] += ad[rot];    ad[rot] = 0;}void update(int L, int R, int p, int l, int r, int rot){    if (L <= l && R >= r)    {        num[rot] += p;        ad[rot] += p;        return;    }    pushdown(rot);    int mid;    if (L <= mm) update(L,R,p,lson);    if (R > mm) update(L,R,p,rson);    pushup(rot);}int main(){#ifndef ONLINE_JUDGE    freopen("in.txt", "r", stdin);#endif // ONLINE_JUDGE    while (scanf("%d%d%d", &n, &w, &h) != EOF && n!=-1)    {        cn = 0;        w *= 2; h *= 2;        for (int i = 0; i< n; ++i)        {            scanf("%d%d", &da[i].x, &da[i].y);            da[i].x *= 2; da[i].y *= 2;            cx[cn++] = da[i].x - w/2;            cx[cn++] = da[i].x + w/2;        }        sort(da, da+n);        sort(cx, cx+cn);        cn = unique(cx,cx+cn) - cx;        cx[cn] = cx[cn-1]+1;        ++cn;        for (int i = 0; i< n; ++i)        {            da[i].l = lower_bound(cx,cx+cn, da[i].x - w/2) - cx;            da[i].r = lower_bound(cx,cx+cn, da[i].x + w/2) - cx;        }        build(0, cn-1, 1);        int res = 0;        for (int i = 0, j=-1, k; i< n; )        {            for (k = j+1; k < n && da[i].y+h >= da[k].y; ++k)                update(da[k].l, da[k].r, 1, 0, cn-1, 1);            j = k-1;            res = max(res, num[1]);            if (k == n) break;            for (k = da[i].y; i< n && da[i].y==k; ++i)                update(da[i].l, da[i].r, -1, 0, cn-1, 1);        }        printf("%d\n", res);    }    return 0;}


0 0