形式上,范围最小查询问题是:
给定一个数组 A[0, N-1] ,找到任意两个给定索引之间具有最小值的元素的位置。
现在,标准解决方案是使用分段树,并在此处进行了描述。另一种用于解决范围查询的数据结构是二叉索引树(Fenwick Tree),它更容易理解和编码。
Binary-Indexed-Trees 可以解决范围最小查询问题吗?如何解决?更新和查询功能的实现将不胜感激。
形式上,范围最小查询问题是:
给定一个数组 A[0, N-1] ,找到任意两个给定索引之间具有最小值的元素的位置。
现在,标准解决方案是使用分段树,并在此处进行了描述。另一种用于解决范围查询的数据结构是二叉索引树(Fenwick Tree),它更容易理解和编码。
Binary-Indexed-Trees 可以解决范围最小查询问题吗?如何解决?更新和查询功能的实现将不胜感激。
尽管有其他答案,但可以将 Fenwick 树用于任何范围的最小范围查询。我在这里发布了详细的解释:
简而言之,你需要维护
i-(i&-i)
i+(i&-i)
查询 O(log n) 中的任何范围
Query(int a, int b) {
int val = infinity // always holds the known min value for our range
// Start traversing the first tree, BIT1, from the beginning of range, a
int i = a
while (parentOf(i, BIT1) <= b) {
val = min(val, BIT2[i]) // Note: traversing BIT1, yet looking up values in BIT2
i = parentOf(i, BIT1)
}
// Start traversing the second tree, BIT2, from the end of range, b
i = b
while (parentOf(i, BIT2) >= a) {
val = min(val, BIT1[i]) // Note: traversing BIT2, yet looking up values in BIT1
i = parentOf(i, BIT2)
}
val = min(val, REAL[i])
return val
}
要更新摊销 O(log n) 中的任何值,您需要更新真实数组和两棵树。更新一棵树:
while (node <= n+1) {
if (v > tree[node]) {
if (oldValue == tree[node]) {
v = min(v, real[node])
for-each child {
v = min(v, tree[child])
}
} else break
}
if (v == tree[node]) break
tree[node] = v
node = parentOf(node, tree)
}
通常,可以针对任何可逆运算(例如加法、乘法)调整 Fenwick 树。
至少可以使用 Fenwick 树来回答形式为 0...x 的区间的查询(左点固定为 0)。这是在对位置 x 的更新操作仅降低存储值的假设下。
我想知道自己是否有同样的问题。但是,我认为芬威克树不可能执行最小/最大查询,这是因为它依赖于从 a 到 b 的累积频率是 f(b)-f(a-1) 的事实,并且属性对 min/max 函数无效