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

题意:平面上有n个点,选一个W×H的矩形,使得矩形内的点最多。

思路:简单的扫描线+线段树,但是调了好久,时间长不写就sb了,哎。。。。线段树中的节点表示以这个节点开始,长度为W的区间内的点的个数。y从小到大扫过去就行了。


代码:


#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<map>
#include<queue>
#include<stack>
#include<set>
#include<cmath>
#include<vector>
#include<bitset>
#define inf 0x3f3f3f3f
#define Inf 0x3FFFFFFFFFFFFFFFLL
#define eps 1e-6
#define pi acos(-1.0)
using namespace std;
typedef long long ll;
const int maxn = 100000 + 10;
struct Point
{
    int x,y,z;
    Point(int x = 0,int y = 0,int z = 0):x(x),y(y),z(z){}
    bool operator < (const Point & a) const
    {
        if(y == a.y) return x < a.x;
        return y < a.y;
    }
}pt[maxn],S[maxn];
int maxv[maxn<<2],addv[maxn<<2];
bool cmp(Point a,Point b)
{
    return a.x < b.x;
}
inline void PushUp(int rt)
{
    maxv[rt] = max(maxv[rt<<1],maxv[rt<<1|1]);
}
void PushDown(int rt)
{
    if(addv[rt])
    {
        addv[rt<<1] += addv[rt];
        addv[rt<<1|1] += addv[rt];
        maxv[rt<<1] += addv[rt];
        maxv[rt<<1|1] += addv[rt];
        addv[rt] = 0;
    }
}
void build(int l,int r,int rt)
{
    maxv[rt] = addv[rt] = 0;
    if(l == r) return ;
    int m = (l + r)>>1;
    build(l,m,rt<<1);
    build(m + 1,r,rt<<1|1);
}
void Update(int L,int R,int l,int r,int rt,int v)
{
    if(l >= L && r <= R)
    {
        addv[rt] += v;
        maxv[rt] += v;
        return ;
    }
    PushDown(rt);
    int m = (l + r)>>1;
    if(m >= L) Update(L,R,l,m,rt<<1,v);
    if(m < R) Update(L,R,m + 1,r,rt<<1|1,v);
    PushUp(rt);
}
int main()
{
//    freopen("in.txt","r",stdin);
    //freopen("out.txt","w",stdout);
    int n,W,H;
    while(~scanf("%d",&n))
    {
        if(n < 0) break;
        scanf("%d%d",&W,&H);
        int x,y,N = 0;
        for(int i = 0;i < n;++i)
        {
            scanf("%d%d",&x,&y);
            pt[i].x = x + 20001;
            pt[i].y = y + 20001;
            N = max(N,pt[i].x);
         }
         build(1,N,1);
         sort(pt,pt + n);
         for(int i = 0;i < n;++i)
         {
             S[i].z = pt[i].y;
             S[i].x = pt[i].x - W;
             S[i].y = pt[i].x;
             S[i].x = max(S[i].x,1);
             S[i].y = min(S[i].y,N);
         }
         int ans = 0,last = 0;
         for(int i = 0;i < n;++i)
         {
             Update(S[i].x,S[i].y,1,N,1,1);
             while(last <= i && S[i].z - S[last].z > H)
                Update(S[last].x,S[last].y,1,N,1,-1),last++;
             ans = max(ans,maxv[1]);
         }
         printf("%d\n",ans);
    }
    return 0;
}


你可能感兴趣的:(数据结构)