现在的位置: 首页 > 综合 > 正文

hdu 5091 Beam Cannon(线段树)

2018年04月03日 ⁄ 综合 ⁄ 共 1749字 ⁄ 字号 评论关闭

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,rr
const 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;
}

抱歉!评论已关闭.