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
- HDU 5091 线段树扫描线
- hdu 5091 线段树+扫描线
- HDU - 5091(扫描线 + 线段树优化)
- HDU 5091 扫描线,线段树
- hdu 5091 线段树+扫描线思想
- hdu 5091 (线段树,扫描线)
- HDU 5091 线段树扫描线
- hdu 5091 Beam Cannon(线段树 + 扫描线)
- hdu 5091 Beam Cannon(线段树扫描线)
- HDU 5091 Beam Cannon(扫描线 + 线段树)
- hdu 5091 Beam Cannon (线段树+扫描线)
- hdu 5091 Beam Cannon 离散化+扫描线+线段树
- HDU 5091 Beam Cannon 线段树+扫描线
- hdu 1542 线段树扫描线
- hdu 3265 Posters 线段树+扫描线
- hdu 1828 线段树+扫描线
- hdu 3265 线段树+扫描线
- hdu 4007 扫描线 线段树
- 一个手机海报合成程序
- fiddler https抓包失败原因 解决
- DAY1 Jun23
- Activity 切换动画
- Qt之QImageWriter
- HDU 5091 扫描线,线段树
- ubuntu启动无桌面图标?
- Linux 下用shell脚本对SVN 修改的文件进行备份
- 可以增删改的输入下拉框(本人原创)
- springMVC注解
- C++STL之vector
- android序列化之Serializable,Parcelable
- SpringMvc基本讲解
- 一致性哈希算法