提问人:cracra 提问时间:2/23/2020 更新时间:2/24/2020 访问量:586
段并集的连接组件
Connected components in union of segments
问:
我在一维数字线上有 N 段(1 ≤ N ≤ 10^5)。每个线段包含所有实数 x,使得起点 x ≤≤终点。
我们可以说,一组段的“并集”是包含在至少一个段中的所有 x 的集合。一组段的“复杂性”是其并集中表示的连接区域的数量。
在段的所有 2^n 个子集上,我们想要计算复杂度的总和。
例:
你有三个段,[1, 6]、[2, 3]、[4, 5],其中 [a, b] a = 起点,b = 终点。
解决方案是 8。以下是每个子集的复杂性: [1,6]⟹1,[2,3]⟹1,[4,5]⟹1
{[1,6],[2,3]}⟹1,{[1,6],[4,5]}⟹1,{[2,3],[4,5]}⟹2
{[1,6],[2,3],[4,5]}⟹1
答案是1+1+1+1+1+2+1=8。
显然,我们不能遍历所有子集(2^N 个子集!谁能给我一个提示或推动我朝着正确的方向前进?
答:
2赞
David Eisenstat
2/23/2020
#1
我假设您熟悉用于计算给定子集的连接分量的标准扫描线算法。
这个想法本质上是同时扫描所有子集。在扫描了开始事件和结束事件之后,有一些子集的扫描点不属于联合。然后,在开始事件中,我们将此计数添加到总复杂度中。2**n
s
e
2**(e+n-s)
在 Python 中:
def total_complexity(segments):
segments = list(segments)
events = [(segment[i], i) for segment in segments for i in range(2)]
events.sort()
total = 0
ended = 0
not_started = len(segments)
for t, is_end in events:
if is_end:
ended += 1
else:
not_started -= 1
total += 2 ** (ended + not_started)
return total
print(total_complexity([(1, 6), (2, 3), (4, 5)]))
评论
1赞
cracra
2/23/2020
您将如何在 O(NlogN) 中解决它?时间限制是一秒,但我基本上最多可以做 10^8 次操作。
0赞
cracra
2/23/2020
或某种程度的 10^8
0赞
cracra
2/23/2020
另外,你的复发中的T是什么?
1赞
David Eisenstat
2/24/2020
@cracra 这个解决方案被破坏了。我用一个希望正确的覆盖了它。
0赞
cracra
2/24/2020
好的,谢谢,我想知道发生了什么!此解决方案的时间复杂度是多少?
上一个:奶牛兼容性 USACO
下一个:在网格上移动 L 形部件
评论