正式地,范围最小查询问题是:
给定一个数组A [0,N-1],找到任意两个给定索引之间具有最小值的元素的位置。
现在,标准解决方案是使用分段树,并且已经描述了here。用于解决范围查询的另一个数据结构是二进制索引树(Fenwick树),它更容易理解和编码。
可以通过二进制索引树来解决范围最小查询问题,以及如何解决?将会感谢更新和查询功能的实现。
答案 0 :(得分:5)
尽管有其他答案,但可以将Fenwick树用于任何范围的范围最小查询。我在这里发布了一个详细的解释:
How to adapt Fenwick tree to answer range minimum queries
简而言之,您需要维护
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)
}
答案 1 :(得分:2)
通常,可以针对任何可逆操作(例如加法,乘法)调整Fenwick树。
对于最小值,可以使用Fenwick树来回答0 ... x形式的间隔的查询(左点固定为0)。这是假设对位置x的更新操作仅降低存储值。
答案 2 :(得分:1)
我想知道同样的问题。但是,我认为fenwick树不可能执行最小/最大查询,这是因为它依赖于从a到b的累积频率为f(b)-f(a-1)的事实,属性对于最小/最大函数
无效