给定数组arr [0。 。 。 n-1]。任务是执行以下操作:
- 查找从索引l到r的元素的最大值,其中0 <= l <= r <= n-1。
- 将数组的指定元素的值更改为新值x。给定i和x,将A [i]更改为x,0 <= i <= n-1。
例子:
Input: a[] = {2, 6, 7, 5, 18, 86, 54, 2}
Query1: maximum(2, 7)
Query2: update(3, 90)
Query3: maximum(2, 6)
Output:
Maximum in range 2 to 7 is 86.
Maximum in range 2 to 6 is 90.
我们已经讨论了递归段树的实现。在这篇文章中,讨论了迭代实现。段树的迭代版本主要使用以下事实:对于索引i,树中的左子节点= 2 * i,右子节点= 2 * i + 1。可以通过parent = i / 2找到分段树数组中索引i的父级。因此,我们可以轻松地在树的各个层次上上下移动。首先,我们计算范围内的最大值,同时构造从叶节点开始并逐层爬升的树。在处理查询以查找范围内的最大值时,我们使用相同的概念。由于在最坏的情况下有(log n)个级别,因此查询花费log n时间。为了将特定索引更新为给定值,我们开始从叶节点开始更新段树,并通过在每次迭代中逐步上移级别来更新受当前节点更新影响的所有那些节点。更新也需要花费n倍的时间,因为我们必须从叶节点开始更新所有级别,在该叶节点处,我们将根据用户指定的确切索引来更新确切值。
下面是上述方法的实现。
C++
// C++ Program to implement
// iterative segment tree.
#include
using namespace std;
void construct_segment_tree(vector& segtree,
vector& a, int n)
{
// assign values to leaves of the segment tree
for (int i = 0; i < n; i++)
segtree[n + i] = a[i];
/* assign values to internal nodes
to compute maximum in a given range */
for (int i = n - 1; i >= 1; i--)
segtree[i] = max(segtree[2 * i],
segtree[2 * i + 1]);
}
void update(vector& segtree, int pos, int value,
int n)
{
// change the index to leaf node first
pos += n;
// update the value at the leaf node
// at the exact index
segtree[pos] = value;
while (pos > 1) {
// move up one level at a time in the tree
pos >>= 1;
// update the values in the nodes in
// the next higher level
segtree[pos] = max(segtree[2 * pos],
segtree[2 * pos + 1]);
}
}
int range_query(vector& segtree, int left, int
right,
int n)
{
/* Basically the left and right indices will move
towards right and left respectively and with
every each next higher level and compute the
maximum at each height. */
// change the index to leaf node first
left += n;
right += n;
// initialize maximum to a very low value
int ma = INT_MIN;
while (left < right) {
// if left index in odd
if (left & 1) {
ma = max(ma, segtree[left]);
// make left index even
left++;
}
// if right index in odd
if (right & 1) {
// make right index even
right--;
ma = max(ma, segtree[right]);
}
// move to the next higher level
left /= 2;
right /= 2;
}
return ma;
}
// Driver code
int main()
{
vector a = { 2, 6, 10, 4, 7, 28, 9, 11, 6, 33 };
int n = a.size();
/* Construct the segment tree by assigning
the values to the internal nodes*/
vector segtree(2 * n);
construct_segment_tree(segtree, a, n);
// compute maximum in the range left to right
int left = 1, right = 5;
cout << "Maximum in range " << left << " to "
<< right << " is " << range_query(segtree, left,
right + 1, n)
<< "\n";
// update the value of index 5 to 32
int index = 5, value = 32;
// a[5] = 32;
// Contents of array : {2, 6, 10, 4, 7, 32, 9, 11, 6, 33}
update(segtree, index, value, n);
// compute maximum in the range left to right
left = 2, right = 8;
cout << "Maximum in range " << left << " to "
<< right << " is " << range_query(segtree,
left, right + 1, n)
<< "\n";
return 0;
}
Python3
# Python Program to implement
# iterative segment tree.
from sys import maxsize
INT_MIN = -maxsize
def construct_segment_tree(a: list, n: int):
global segtree
# assign values to leaves of the segment tree
for i in range(n):
segtree[n + i] = a[i]
# assign values to internal nodes
# to compute maximum in a given range */
for i in range(n - 1, 0, -1):
segtree[i] = max(segtree[2 * i], segtree[2 * i + 1])
def update(pos: int, value: int, n: int):
global segtree
# change the index to leaf node first
pos += n
# update the value at the leaf node
# at the exact index
segtree[pos] = value
while pos > 1:
# move up one level at a time in the tree
pos //= 2
# update the values in the nodes in
# the next higher level
segtree[pos] = max(segtree[2 * pos], segtree[2 * pos + 1])
def range_query(left: int, right: int, n: int) -> int:
global segtree
# Basically the left and right indices will move
# towards right and left respectively and with
# every each next higher level and compute the
# maximum at each height.
# change the index to leaf node first
left += n
right += n
# initialize maximum to a very low value
ma = INT_MIN
while left < right:
# if left index in odd
if left & 1:
ma = max(ma, segtree[left])
# make left index even
left += 1
# if right index in odd
if right & 1:
# make right index even
right -= 1
ma = max(ma, segtree[right])
# move to the next higher level
left //= 2
right //= 2
return ma
# Driver Code
if __name__ == "__main__":
a = [2, 6, 10, 4, 7, 28, 9, 11, 6, 33]
n = len(a)
# Construct the segment tree by assigning
# the values to the internal nodes
segtree = [0] * (2 * n)
construct_segment_tree(a, n)
# compute maximum in the range left to right
left = 1
right = 5
print("Maximum in range %d to %d is %d" %
(left, right, range_query(left, right + 1, n)))
# update the value of index 5 to 32
index = 5
value = 32
# a[5] = 32;
# Contents of array : {2, 6, 10, 4, 7, 32, 9, 11, 6, 33}
update(index, value, n)
# compute maximum in the range left to right
left = 2
right = 8
print("Maximum in range %d to %d is %d" %
(left, right, range_query(left, right + 1, n)))
# This code is contributed by
# sanjeev2552
输出:
Maximum in range 1 to 5 is 28
Maximum in range 2 to 8 is 32
时间复杂度: (N * log N)
辅助空间: O(N)