离散化 + 扫描线 + 线段树 hdu 4007

题意简单: 求长度为R的正方形区域中,最多包含多少个点,正方形边界上的点也算。

poj 2482 是同样的问题,但是不算边界上的点。(优美的情书啊,可以学习下)

#include <cstdio>
#include <iostream>
#include <queue>
#include <cstring>
#include <vector>
#include <algorithm>

using namespace std;

const int maxn = 2000+10;
struct people{
  long long x, y;
};
people p[maxn];

bool cmp(people a, people b){
  return a.x - b.x < 0;
}
int st[8*maxn];
int setv[8*maxn];
long long py[2*maxn];


void build(int root, int l, int r){
  if(l < r){
    int mid = (l+r)/2;
    build(2*root, l, mid);
    build(2*root+1, mid+1, r);
  }else{
    st[root] = setv[root] = 0;
  }
}

void pushdown(int root, int l, int r){
  if(setv[root]){
    int lc = 2*root, rc = 2*root+1, mid = (l+r)/2;
    setv[lc] += setv[root];
    setv[rc] += setv[root];
    st[lc] += setv[root];
    st[rc] += setv[root];
    setv[root] = 0;
  }
}

void pushup(int root, int l, int r){
    int lc = 2*root, rc = 2*root+1;
    st[root] = max(st[lc], st[rc]);
}

void modify(int root, int l, int r, int x, int y, int z){
  if(x <= l && r <= y){
    setv[root] += z;
    st[root] += z;
  }else{
    pushdown(root, l, r);
    int mid = (l+r)/2;
    if(x <= mid) modify(2*root, l, mid, x, y, z);
    if(y > mid) modify(2*root+1, mid+1, r, x, y, z);
    pushup(root, l, r);
  }
}



int main(){
  int n, r;
  while(scanf("%d%d", &n, &r) != EOF){
    memset(setv, 0, sizeof(setv));
    memset(st, 0, sizeof(st));
    for(int i = 1; i <= n; i ++){
      scanf("%lld %lld", &p[i].x, &p[i].y);
      //cin >> p[i].x >> p[i].y ;
     // cout << p[i].x << " " << p[i].y << endl;
      py[i] = p[i].y; py[i+n] = p[i].y + r ;
    }
    sort(py+1, py+2*n+1);
    int m = unique(py+1, py+2*n+1)-py-1;
    build(1, 1, m);
    sort(p+1, p+n+1, cmp);
    int j = 1;
    int ans = 0;
    for(int i = 1; i <= n; i ++){
      int l1 = lower_bound(py+1, py+m+1, p[i].y)-py;
      int r1 = lower_bound(py+1, py+m+1, p[i].y+r)-py;
      modify(1, 1, m, l1, r1, 1);
      while(j <= i && p[j].x < p[i].x-r){
        int ll = lower_bound(py+1, py+m+1, p[j].y) - py;
        int rr = lower_bound(py+1, py+m+1, p[j].y+r) - py;
        modify(1, 1, m, ll, rr, -1);
        j ++;
      }
      if(st[1] > ans) ans = st[1];
    }
    printf("%d\n", ans);
  }
  return 0;
}





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值