HDU 5091 扫描线,线段树

来源:互联网 发布:植物转录因子数据库 编辑:程序博客网 时间:2024/06/16 12:38

题意:给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 ;}@Overridepublic int compareTo(Line other){if(x != other.x) return Integer.compare(x , other.x) ;return Integer.compare(val , other.val) ;}@Overridepublic 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());}}


0 0
原创粉丝点击