为什么/何时使用分段树进行范围最小查询?

问题描述

我了解到,使用段树实现范围最小查询,需要花费O(n)的时间进行预处理,并花费O(log(n))的时间来找到每个查询解决方案。它也需要额外的空间。

如果相反,我们只是简单地找到某个数组的某个子数组的最小值,则可以在O(n)中找到它。

然后,为什么要使用段树实现?什么是物流?
与常数有关吗?
细分树特别有用吗?

解决方法

有许多结构可让您在亚线性时间内对阵列进行大量操作。我将它们分为两类:固定的和动态的。

固定的结构具有出色的查询运行时性能,但不支持数组更新。RMQ允许您在恒定时间查询(使用O(n log n) precomp和内存)中进行min / max / gcd范围的设置,但不支持更新。前缀总和使您可以在恒定时间内获得范围总和,但不支持更新。这两个都是固定结构的示例,因为数组中的更新将需要对结构进行几乎完全的重新计算。

动态结构会牺牲更多的内存和时间来支持更广泛的操作。 BIT /分域树使您可以进行点更新,每次操作的范围总和为O(log n)。这种结构的开销低于段树,在仅需要这些操作的情况下很有用。然后当然是:段树

段树支持范围最小/最大/ gcd查询,例如RMQ。它们还支持范围总和,例如BIT /前缀总和。这些查询支持更新,因此您可以像上面那样进行点更新。但是,只要稍微聪明一点,他们就能做得更多!细分树很容易修改以支持范围更新(向范围中的每个元素添加/减去一个值)。它们可以支持点集和范围集查询(将范围内的所有值设置为所需值)。它们可以支持范围按位运算(AND,OR,XOR)。它们可以支持范围计数(对预定的期望数进行计数),或者返回查询值的第一个/最后一个索引。

这些只是可以轻松修改段树以支持的一些操作。可能性非常广泛,这就是为什么分段树对于那么多应用程序如此有用的原因。认识他们非常重要,练习如何将他们的力量运用到解决问题上是非常有用的技能。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...