给定N个水平线段,其中包含起点和终点(即A和B),对重叠标准没有限制。这意味着我们有从(A,0)到(B,0)的线段。现在我们可以绘制两条穿过这些线的垂直线。我们需要找到这两条线可以交叉的最大线段。 (如果垂直线接触任何水平线段,也要计算)
示例:假设我们有5个线段:
2 3
1 3
1 5
3 4
4 5
然后我们将绘制两条线(平行于Y轴)在第2点和第4点与X轴交叉。这两条线将触及所有五个线段。所以答案为5。
但我们假设我们有3个线段:
1 2
3 4
5 6
然后回答为2,因为在这种情况下不可能触摸超过两点。
如何解决这个问题?请帮忙。
注意1≤N≤10^ 5且0≤A<1。 B≤10^ 9答案 0 :(得分:0)
以下是此问题的一些提示。
将变量计数设置为0。
现在对开始和结束事件进行排序,并按递增顺序循环事件。
如果您看到开始事件,请将计数增加1。
如果您看到结束事件,请将计数减少1。
在算法的每一步,count都会给出与当前x位置重叠的区间数。
上面的提示显示了如何找到重叠最多间隔的单行。
但是,我们想要找到2行。所以我们需要做的是能够找到跨越最多间隔的第二条线 - 不包括触及第一条线的间隔。
您可以使用具有延迟传播的分段树(C ++代码here)。这允许您在时间O(logn)中添加间隔/查询最大值。
您可以将此与提示1结合使用,只有在看到结束事件时才向段树添加间隔。
在伪代码中,完整的算法将是:
For each event in sorted order:
if event.type==start: count += 1
if event.type==end: count -= 1 and update segment tree to add 1 to all points in range event.start to event.end
current_value = count + maximum value in segment tree
best_value = max(best_value,current_value)
初始排序的总体复杂度为O(nlogn),加上扫描的O(nlogn)以找到最佳线对。