题意:给n个点,和长w宽h的矩形,问矩形最多能包含多少个点(边界也算)。
1、离散化;
2、考虑点(x,y),那么右上角为{ (x,y)~(x+W,y+H) }的矩形可以覆盖点(x,y);
于是对于点(x,y)转化成线段(x , y , y+H , 进来1) , (x+W+1 , y , y+h , 出去0) , 这里y+H+1一样效果;
3、按y轴建立线段树,维护最大值;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.math.BigInteger;
import java.util.Arrays;
import java.util.StringTokenizer;
public class Main {
public static void main(String[] args) {
new HDU5091().solve();
}
}
class HDU5091 {
InputReader in = new InputReader(System.in);
PrintWriter out = new PrintWriter(System.out);
final int N = 20008 ;
int[] lx = new int[N] ;
int[] rx = new int[N] ;
int[] ly = new int[N] ;
int[] ry = new int[N] ;
int[] x = new int[N<<1] ;
int[] y = new int[N<<1] ;
Line[] line = new Line[N<<1] ;
SegmentTree tree = new SegmentTree() ;
void solve() {
int w , h , n , xsize , ysize ;
while(true){
n = in.nextInt() ;
if(n < 0) break ;
w = in.nextInt() ;
h = in.nextInt() ;
xsize = ysize = 0 ;
for(int i = 0 ; i < n ; i++){
lx[i] = in.nextInt() ;
ly[i] = in.nextInt() ;
rx[i] = lx[i] + w + 1 ;
ry[i] = ly[i] + h ;
x[xsize++] = lx[i] ;
x[xsize++] = rx[i] ;
y[ysize++] = ly[i] ;
y[ysize++] = ry[i] ;
}
Arrays.sort(x , 0 , xsize) ;
Arrays.sort(y , 0 , ysize) ;
int[] X = Std.unique(x , 0 , xsize) ;
int[] Y = Std.unique(y , 0 , ysize) ;
for(int i = 0 ; i < n ; i++){
lx[i] = Std.upper_bound(X , lx[i]) ;
rx[i] = Std.upper_bound(X , rx[i]) ;
ly[i] = Std.upper_bound(Y , ly[i]) ;
ry[i] = Std.upper_bound(Y , ry[i]) ;
}
int lineSize = 0 ;
for(int i = 0 ; i < n ; i++){
line[lineSize++] = new Line(lx[i] , ly[i] , ry[i] , 1) ;
line[lineSize++] = new Line(rx[i] , ly[i] , ry[i] , -1) ;
}
Arrays.sort(line , 0 , lineSize) ;
tree.build(1 , 1 , Y.length) ;
int res = 0 ;
for(int i = 0 ; i < lineSize ; i++){
tree.update(line[i].l , line[i].r , line[i].val , 1 , 1 , Y.length) ;
res = Math.max(res , tree.max[1]) ;
}
out.println(res) ;
}
out.flush() ;
}
}
class Line implements Comparable<Line>{
int x , l , r , val ;
Line(int x , int l , int r , int val){
this.x = x ;
this.l = l ;
this.r = r ;
this.val = val ;
}
@Override
public int compareTo(Line other){
if(x != other.x) return Integer.compare(x , other.x) ;
return Integer.compare(val , other.val) ;
}
@Override
public String toString() {
return "Line [x=" + x + ", l=" + l + ", r=" + r + ", val=" + val + "]";
}
}
class SegmentTree{
final int N = 20008 ;
int[] max = new int[N<<2] ;
int[] add = new int[N<<2] ;
void build(int root , int l , int r){
max[root] = add[root] = 0 ;
if(l == r) return ;
int m = (l + r) >> 1 ;
build(root<<1 , l , m) ;
build(root<<1|1 , m+1 , r) ;
up(root) ;
}
void down(int root){
if(add[root] != 0){
add[root<<1] += add[root] ;
max[root<<1] += add[root] ;
add[root<<1|1] += add[root] ;
max[root<<1|1] += add[root] ;
add[root] = 0 ;
}
}
void up(int root){
max[root] = Math.max(max[root<<1] , max[root<<1|1]) ;
}
void update(int L , int R , int val , int root , int l , int r){
if(L <= l && r <= R){
max[root] += val ;
add[root] += val ;
return ;
}
down(root) ;
int m = (l + r) >> 1 ;
if(L <= m) update(L , R , val , root<<1 , l , m) ;
if(R > m) update(L , R , val , root<<1|1 , m+1 , r) ;
up(root) ;
}
}
class Std{
static int[] unique(int[] array , int l , int r){
if(l == r) return new int[0] ;
int size = 1 ;
for(int i = l+1 ; i < r ; i++){
if(array[i] != array[i-1]) size++ ;
}
int[] res = new int[size] ;
int idx = 0 ;
res[idx++] = array[l] ;
for(int i = l+1 ; i < r ; i++){
if(array[i] != array[i-1]) res[idx++] = array[i] ;
}
return res ;
}
static int[] unique(int[] array){
return unique(array , 0 , array.length) ;
}
static int upper_bound(int[] array , int l , int r , int val){
int res = r , m ;
r-- ;
while(l <= r){
m = (l + r) >> 1 ;
if(array[m] > val){
res = m ;
r = m - 1 ;
}
else l = m + 1 ;
}
return res ;
}
static int upper_bound(int[] array , int val){
return upper_bound(array , 0 , array.length , val) ;
}
}
class InputReader {
public BufferedReader reader;
public StringTokenizer tokenizer;
public InputReader(InputStream stream) {
reader = new BufferedReader(new InputStreamReader(stream), 32768);
tokenizer = null;
}
public String next() {
while (tokenizer == null || !tokenizer.hasMoreTokens()) {
try {
tokenizer = new StringTokenizer(reader.readLine());
} catch (IOException e) {
throw new RuntimeException(e);
}
}
return tokenizer.nextToken();
}
public int nextInt() {
return Integer.parseInt(next());
}
public long nextLong() {
return Long.parseLong(next());
}
public double nextDouble() {
return Double.parseDouble(next());
}
public BigInteger nextBigInteger() {
return new BigInteger(next());
}
}