poj 2482 java

本文介绍了一种使用二维扫描线算法解决最大矩形面积问题的方法。该算法通过构建一棵线段树来跟踪不同高度的矩形区域,并利用TreeSet对Y坐标进行排序,以确保能够高效地更新和查询当前的最大面积。
import java.util.*;

public class POJ_2482 {

	static long height[];
	static long tree[];
	static XY p[];
	static TreeSet<Long> ts;
	static Iterator<Long> iterator;
	static int m;
	static long sum[];
	static long maxSum[];
	
	public static void main(String[] args)throws Exception {
		
		Scanner scan = new Scanner(System.in);
		
		while(scan.hasNext()){
			int n = scan.nextInt();
			int W = scan.nextInt();
			int H = scan.nextInt();
			height = new long[2*n];
			ts = new TreeSet<Long>();
			
			p = new XY[n<<1];
			
			for(int i=0;i<n;i++){
				p[i] = new XY(scan.nextLong(),scan.nextLong(),scan.nextLong());
				p[i+n] = new XY(p[i].x+W,p[i].y,-p[i].c);    //x扫描线  当遇到 p[i].x+W 表示 以p[i].x为左下角的矩形已搜索结束
				ts.add(p[i].y);                              // 所以是  -p[i].c  这样刚好可以中和  成0  表示没有加上它
				ts.add(p[i].y+H);
			}
			m = ts.size();
			iterator = ts.iterator();
			tree = new long[m<<1];
			sum = new long[(m<<1)+2];
			maxSum = new long[(m<<1)+2];
			
			createLineTree(1);
			
			java.util.Arrays.sort(p);
			
			n *= 2;
			
			long ans = 0;
			for(int i=0;i<n;i++){             //原理同 x扫描线 相似
				insert(p[i].y,p[i].c);
				insert(p[i].y+H,-p[i].c);
				ans = Math.max(ans, maxSum[1]);
			}
			System.out.println(ans);
		}

	}

	private static void insert(long y, long c) {
		
		int p = 1;
		while(tree[p]!=y){            // 搜索要修改的点
			if(y<tree[p])
				p <<= 1;
			else
				p = (p<<1)+1;
		}
		
		while(p!=0){                         //更新 前面找到的修改点以及 它所有祖先点
			sum[p] += c;
			long t1 = maxSum[2*p];            // 每个根结点 是 左右子树 一起更新的结果
			long t2 = sum[p]-sum[2*p+1]+maxSum[2*p+1];  //  因为此树是有序的 所以每一棵子树 代表一个范围 (左根右) 
			maxSum[p] = Math.max(t1, t2);               // 而这个范围的maxSum 值 就放在根中   根中的sum值 是其所有子树的总和
			p /= 2;
		}
		
	}

	public static void createLineTree(int p) {
		
		if(2*p<=m)                      // 建立二叉 排序树   
			createLineTree(2*p);
		tree[p] = iterator.next();
		if(2*p+1<=m)
			createLineTree(2*p+1);
	}

}
class XY implements Comparable<XY>{

	long x;
	long y;
	long c;
	
	public XY(long x, long y, long c) {
		super();
		this.x = x;
		this.y = y;
		this.c = c;
	}


	public int compareTo(XY e) {
		
		if(this.x<e.x)
			return -1;
		else if(this.x>e.x)
			return 1;
		else{
			if(this.c<e.c)
				return -1;
			else if(this.c>e.c)
				return 1;
			return 0;
		}
		
	}
	
}


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值