HDU 4007 Dave【离散化+扫描线】

题意: 知道了 n 个人的坐标和一个边长为R的正方形,问正方形内最多可以包含多少人。

分析:离散化坐标,将y坐标映射到区间上,按x坐标从小到达扫描。

#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
#define maxn 10005
long long max(long long a, long long b)
{
    return a>b?a:b;
}
struct seg
{
    long long x, y, val;
}s[maxn*2];

int add[maxn<<3];
int val[maxn<<3];
long long Y[maxn*2];

bool cmp(seg a, seg b)
{
    if(a.x != b.x)
        return a.x < b.x;
    return a.val < b.val;
}

void update(long long L, long long R, long long va, long long l, long long r, long long rt)
{
    if (L <= l && r <= R)
    {
        add[rt] += va;
        val[rt] += va;
        return;
    }

    if (add[rt])
    {
        add[rt<<1] += add[rt];
        add[rt<<1|1] += add[rt];
        val[rt<<1] += add[rt];
        val[rt<<1|1] += add[rt];
        add[rt] = 0;
    }
    long long m = (l + r)>>1;
    if (L <= m)
        update(L, R, va, l, m, rt<<1);
    if (R > m)
        update(L, R, va, m+1, r, rt<<1|1);
    val[rt] = max(val[rt<<1], val[rt<<1|1]);
}

long long b_search(long long key, long long n)
{
    long long m, l = 1, r = n;
    while (l <= r)
    {
        m = (l+r)>>1;
        if (Y[m] == key)
            return m;
        else if (Y[m] > key)
            r = m-1;
        else l = m+1;
    }
    return -1;
}
int main()
{
    long long i, m, l, r, res;
    long long n, R;
    while (scanf("%I64d %I64d",&n, &R) != EOF)
    {
        for (i=1; i<=n; i++)
        {
            scanf("%I64d %I64d",&s[i].x, &s[i].y);
            s[i].val = 1;
            s[i+n] = s[i];
            s[i+n].x = s[i].x + R +1;
            s[i+n].val = -1;
            Y[i] = s[i].y;
            Y[i+n] = s[i].y+R;
        }

        sort(Y+1, Y+2*n+1);
        sort(s+1, s+2*n+1, cmp);

        m = 1;
        for (i=1; i<=2*n; i++)
            if (Y[i] != Y[m])
                Y[++m] = Y[i];
        memset(add, 0, sizeof(add));
        memset(val,0,sizeof(val));
        res = 0;
        for (i=1; i<=2*n; i++)
        {
            l = b_search(s[i].y, m);
            r = b_search(s[i].y+R, m);
            update(l, r, s[i].val, 1, m, 1);
            res = max(res,val[1]);
        }
        printf("%I64d\n",res);
    }
    return 0;
}

 

posted @ 2012-11-03 13:09  'wind  阅读(359)  评论(0编辑  收藏  举报