我们如何证明段树(http://letuskode.blogspot.in/2013/01/segtrees.html)上的update
和query
操作(不要与间隔树混淆)是O(log n)
?< / p>
我想到了一种这样的方式 - 在每个节点,我们在左右子树上最多进行两次递归调用。如果我们能够证明其中一个呼叫相当快地终止,那么时间复杂度将以对数为界。但是我们如何证明这一点?
答案 0 :(得分:10)
引理:树的每个级别最多使用2个节点(一个级别是与根目录固定距离的节点集)。
证明:我们假设在h
级别使用了至少3个节点(让他们称之为L
,M
和R
)。这意味着从L
节点的左边界到R
节点的右边界的整个间隔位于查询范围内。这就是为什么M
完全由一个节点(让我们称之为UP
)从完全位于查询范围内的h - 1
级别覆盖的原因。但这意味着根本无法访问M
,因为遍历将在UP
节点或更高节点停止。以下是一些图片,以澄清证明的这一步骤:
h - 1: UP UP UP
/\ /\ /\
h: L M R L M R L M R
这就是为什么每个级别最多使用两个节点的原因。段树中只有log N
个级别,因此总共使用2 * log N
个{{1}}级别。
答案 1 :(得分:0)
T(l, r)
和n = l - r
,最多可以使用2 * log n
个节点。如果是,对于T(1, 17)
,可以使用8个节点,但真正的答案实际上是6.答案应该是2 * log n - 2
,因为他假设我们可以使用1级的两个节点。在这种情况下,我们需要获取根而不是1级节点。此外,我们无法获得这两个节点中的任何一个,因为这意味着在更高级别中没有使用节点。对于级别1的T(1, 17)
,[1, 9)
和[9-17]
个节点。如果我们使用[1, 9)
,我们会丢弃此节点的子节点,这些节点位于提供最大使用量。
答案 2 :(得分:0)
声称最多有22个节点在每个级别进行扩展。我们将通过矛盾来证明这一点。 考虑下面给出的分段树。
假设有3个节点在此树中展开。这意味着范围是从最左边的彩色节点到最右边的彩色节点。但请注意,如果范围扩展到最右边的节点,则覆盖中间节点的整个范围。因此,此节点将立即返回该值,并且不会展开。因此,我们证明在每个级别,我们最多扩展22个节点,并且因为有lognlogn级别,所以扩展的节点是2⋅logn=Θ(logn)
答案 3 :(得分:0)
如果我们证明每个级别上最多可以访问N个节点,并且知道二进制段树具有最大logN高度-我们可以说查询操作具有O(LogN)复杂度。其他答案告诉您,每个级别上最多可以访问2个节点,但是我假设最多可以访问4个节点,可以访问4个节点。您可以在Geek for Geeks
等其他来源中找到未经证明的同一条语句其他答案显示您的细分树太小。考虑以下示例:叶节点大小为16的段树,索引从零开始。您正在寻找范围[0-14] 参见示例:交叉的是我们正在访问的节点
答案 4 :(得分:0)
在树的每个层(L)处最多有2个节点,这些节点可能有部分重叠。 (如果无法证明-为什么?,请提及)
因此,在(L + 1)级,我们必须探索最多4个节点。树中的总高度/级别为O(log(N))(其中N为节点数)。因此,时间复杂度为O(4 * Log(N))〜O(Log(N))。
PS:请参阅@Oleksandr Papchenko附带的图表,以更好地理解
。