平面内有n个矩形, 第i个矩形的左下角坐标为(x1[i], y1[i]), 右上角坐标为(x2[i], y2[i])。
如果两个或者多个矩形有公共区域则认为它们是相互重叠的(不考虑边界和角落)。
请你计算出平面内重叠矩形数量最多的地方,有多少个矩形相互重叠。
import java.util.*;
public class Main {
/**
* 离散化横坐标
*
* @param rectangles
* @return
*/
private static Map<Integer, Integer> dispersed(Rectangle[] rectangles) {
TreeSet<Integer> treeSet = new TreeSet<>();
for (Rectangle rectangle : rectangles) {
treeSet.add(rectangle.left);
treeSet.add(rectangle.right - 1);
}
int index = 1;
Map<Integer, Integer> retMap = new HashMap<>();
for (int item : treeSet) {
retMap.put(item, index ++);
}
return retMap;
}
private static int solve(Rectangle[] rectangles) {
Arrays.sort(rectangles, new Comparator<Rectangle>() {
@Override
public int compare(Rectangle o1, Rectangle o2) {
return Integer.compare(o1.down, o2.down);
}
});
Map<Integer, Integer> dispersed = dispersed(rectangles);
/**
* 和线段最大重叠问题一样
*/
PriorityQueue<Rectangle> queue = new PriorityQueue<>(new Comparator<Rectangle>() {
@Override
public int compare(Rectangle o1, Rectangle o2) {
return Integer.compare(o1.up, o2.up);
}
});
int segmentSize = dispersed.size();
SegmentTree segmentTree = new SegmentTree(segmentSize);
int L, R;
int ret = 0;
for (Rectangle rectangle : rectangles) {
while (!queue.isEmpty() && queue.peek().up <= rectangle.down) {
Rectangle poll = queue.poll();
L = dispersed.get(poll.left);
R = dispersed.get(poll.right - 1);
segmentTree.add(L, R, -1, 1, segmentSize, 1);
}
queue.offer(rectangle);
L = dispersed.get(rectangle.left);
R = dispersed.get(rectangle.right - 1);
segmentTree.add(L, R, 1, 1, segmentSize, 1);
ret = Math.max(ret, segmentTree.query(L, R, 1, segmentSize, 1));
}
return ret;
}
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
while (in.hasNext()) {
int n = in.nextInt();
Rectangle[] rectangles = new Rectangle[n];
for (int i = 0; i < n; ++i) {
rectangles[i] = new Rectangle();
}
for (int i = 0; i < n; ++i) {
rectangles[i].left = in.nextInt();
}
for (int i = 0; i < n; ++i) {
rectangles[i].down = in.nextInt();
}
for (int i = 0; i < n; ++i) {
rectangles[i].right = in.nextInt();
}
for (int i = 0; i < n; ++i) {
rectangles[i].up = in.nextInt();
}
System.out.println(solve(rectangles));
}
}
}
class SegmentTree {
private int n;
private int[] max;
private int[] lazy;
public SegmentTree(int n) {
this.n = n;
this.max = new int[n << 2 | 1];
this.lazy = new int[n << 2 | 1];
}
private void pushUp(int rt) {
max[rt] = Math.max(max[rt << 1], max[rt << 1 | 1]);
}
private void pushDown(int rt) {
if (lazy[rt] != 0) {
lazy[rt << 1] += lazy[rt];
lazy[rt << 1 | 1] += lazy[rt];
max[rt << 1] += lazy[rt];
max[rt << 1 | 1] += lazy[rt];
lazy[rt] = 0;
}
}
public void add(int L, int R, int V, int l, int r, int rt) {
if (L <= l && r <= R) {
max[rt] += V;
lazy[rt] += V;
return;
}
int mid = (l + r) >> 1;
pushDown(rt);
if (L <= mid) {
add(L, R, V, l, mid, rt << 1);
}
if (mid < R) {
add(L, R, V, mid + 1, r, rt << 1 | 1);
}
pushUp(rt);
}
public int query(int L, int R, int l, int r, int rt) {
if (l == r) {
return max[rt];
}
int mid = (l + r) >> 1;
pushDown(rt);
int ret = 0;
if (L <= mid) {
ret = Math.max(ret, query(L, R, l, mid, rt << 1));
}
if (mid < R) {
ret = Math.max(ret, query(L, R, mid + 1, r, rt << 1 | 1));
}
return ret;
}
}
class Rectangle {
int up;
int down;
int left;
int right;
}
心之所向,素履以往 生如逆旅,一苇以航