形式上,区间最小值查询问题是:
给定一个数组A[0, N-1],找到在任意两个给定索引之间具有最小值的元素的位置。
现在,标准解决方案是使用线段树,并已在这里中描述。另一个用于解决范围查询的数据结构是二进制索引树(Fenwick Tree),它更容易理解和编码。
区间最小查询问题是否可以通过使用二进制索引树来解决?如何实现更新和查询函数?
形式上,区间最小值查询问题是:
给定一个数组A[0, N-1],找到在任意两个给定索引之间具有最小值的元素的位置。
现在,标准解决方案是使用线段树,并已在这里中描述。另一个用于解决范围查询的数据结构是二进制索引树(Fenwick Tree),它更容易理解和编码。
区间最小查询问题是否可以通过使用二进制索引树来解决?如何实现更新和查询函数?
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)
}
我自己也在思考同样的问题。然而,我认为树状数组无法执行最小/最大查询,因为它依赖于从a到b的累积频率是f(b)-f(a-1)这一事实,而该属性对于min/max函数是无效的。