给定N个整数的数组arr [] ,任务是执行以下两个查询:
- query(start,end) :从开始到结束打印子数组中的完美平方数
- update(i,x) :将x添加到数组索引i引用的数组元素中,即:arr [i] = x
注意:在下面的示例中,遵循基于0的索引。
例子:
Input: arr = [ 16, 15, 8, 9, 14, 25 ];
Query 1: query(start = 0, end = 4)
Query 2: update(i = 3, x = 11) i.e. arr[3]=11
Query 3: query(start = 0, end = 4)
Output: 2 1
Explanation:
In Query 1, the sub-array [0…4] has 2 perfect square numbers 16 and 9 viz. [ 16, 15, 8, 9, 14 ]
In Query 2, the value at index 3 is updated to 11,
the array arr now is, [ 16, 15, 8, 11, 14, 25 ]
In Query 3, the sub-array [0…4] has 1 perfect square number 16 viz. [ 16, 15, 8, 11, 14 ]
方法:
为了同时处理点更新和范围查询,为此目的,使用段树是最佳的。
为了检查完美平方数,其思想是首先计算该数字的平方根,如果平方根是整数,则当前元素是一个完美平方。如果当前元素是一个完美的正方形,则将其设置为1,否则将其设置为0。
构建段树:
- 现在,使用分段树问题将问题简化为子数组总和。
- 现在,我们可以构建分段树,其中叶节点表示为0(如果不是理想的平方数)或1(如果是理想的平方数)。
- 段树的内部节点等于其子节点的总和,因此,一个节点代表从L到R的总理想平方数,范围[L,R]落在该节点下,而其下的子树。
处理查询和积分更新:
- 每当我们从头到尾收到查询时,我们都可以在段树中查询从头到尾范围内的节点总数,这又代表从头到尾范围内的完美平方数。
- 为了执行点更新并将索引i的值更新为x,我们检查以下情况:
令arr [i]的旧值为y,新值为x。- 情况1:如果x和y都是理想的平方数
子数组中完美平方数的数量不会改变,因此我们只更新数组而不会修改段树 - 情况2:如果x和y都不是理想的平方数
子数组中完美平方数的数量不会改变,因此我们只更新数组而不会修改段树 - 情况3:如果y是一个完美的平方数,但x不是
子数组中完美平方数的计数减少,因此我们更新数组并将-1添加到每个范围。要更新的索引i是分段树的一部分 - 情况4:如果y不是一个完美的平方数,但x是一个完美的平方数
子数组中完美平方数的计数增加,因此我们更新数组并将每个范围加1。要更新的索引i是分段树的一部分
- 情况1:如果x和y都是理想的平方数
下面是上述方法的实现:
C++
// C++ program to find number of
// perfect square numbers in a
// subarray and performing updates
#include
using namespace std;
#define MAX 1000
// Function to check if a number is
// a perfect square or not
bool isPerfectSquare(long long int x)
{
// Find floating point value of
// square root of x.
long double sr = sqrt(x);
// If square root is an integer
return ((sr - floor(sr)) == 0)
? true
: false;
}
// A utility function to get the middle
// index from corner indexes.
int getMid(int s, int e)
{
return s + (e - s) / 2;
}
// Recursive function to get the number
// of perfect square numbers in a given
// range
/* where
st --> Pointer to segment tree
index --> Index of current node in the
segment tree. Initially 0 is
passed as root is always
at index 0
ss & se --> Starting and ending indexes
of the segment represented by
current node i.e. st[index]
qs & qe --> Starting and ending indexes
of query range */
int queryUtil(int* st, int ss,
int se, int qs,
int qe, int index)
{
// If segment of this node is a part
// of given range, then return
// the number of perfect square numbers
// in the segment
if (qs <= ss && qe >= se)
return st[index];
// If segment of this node
// is outside the given range
if (se < qs || ss > qe)
return 0;
// If a part of this segment
// overlaps with the given range
int mid = getMid(ss, se);
return queryUtil(st, ss, mid, qs,
qe, 2 * index + 1)
+ queryUtil(st, mid + 1, se,
qs, qe, 2 * index + 2);
}
// Recursive function to update
// the nodes which have the given
// index in their range.
/* where
st, si, ss & se are same as getSumUtil()
i --> index of the element to be updated.
This index is in input array.
diff --> Value to be added to all nodes
which have i in range
*/
void updateValueUtil(int* st, int ss,
int se, int i,
int diff, int si)
{
// Base Case:
// If the input index lies outside
// the range of this segment
if (i < ss || i > se)
return;
// If the input index is in range
// of this node, then update the value
// of the node and its children
st[si] = st[si] + diff;
if (se != ss) {
int mid = getMid(ss, se);
updateValueUtil(st, ss, mid, i,
diff, 2 * si + 1);
updateValueUtil(st, mid + 1, se,
i, diff, 2 * si + 2);
}
}
// Function to update a value in the
// input array and segment tree.
// It uses updateValueUtil() to update
// the value in segment tree
void updateValue(int arr[], int* st,
int n, int i,
int new_val)
{
// Check for erroneous input index
if (i < 0 || i > n - 1) {
printf("Invalid Input");
return;
}
int diff, oldValue;
oldValue = arr[i];
// Update the value in array
arr[i] = new_val;
// Case 1: Old and new values
// both are perfect square numbers
if (isPerfectSquare(oldValue)
&& isPerfectSquare(new_val))
return;
// Case 2: Old and new values
// both not perfect square numbers
if (!isPerfectSquare(oldValue)
&& !isPerfectSquare(new_val))
return;
// Case 3: Old value was perfect square,
// new value is not a perfect square
if (isPerfectSquare(oldValue)
&& !isPerfectSquare(new_val)) {
diff = -1;
}
// Case 4: Old value was
// non-perfect square,
// new_val is perfect square
if (!isPerfectSquare(oldValue)
&& !isPerfectSquare(new_val)) {
diff = 1;
}
// Update values of nodes in segment tree
updateValueUtil(st, 0, n - 1, i, diff, 0);
}
// Return no. of perfect square numbers
// in range from index qs (query start)
// to qe (query end).
// It mainly uses queryUtil()
void query(int* st, int n,
int qs, int qe)
{
int perfectSquareInRange
= queryUtil(
st, 0, n - 1, qs, qe, 0);
cout << perfectSquareInRange << "\n";
}
// Recursive function that constructs
// Segment Tree for array[ss..se].
// si is index of current node
// in segment tree st
int constructSTUtil(int arr[], int ss,
int se, int* st,
int si)
{
// If there is one element in array,
// check if it is perfect square number
// then store 1 in the segment tree
// else store 0 and return
if (ss == se) {
// if arr[ss] is a perfect
// square number
if (isPerfectSquare(arr[ss]))
st[si] = 1;
else
st[si] = 0;
return st[si];
}
// If there are more than one
// elements, then recur for
// left and right subtrees
// and store the sum of the
// two values in this node
int mid = getMid(ss, se);
st[si]
= constructSTUtil(arr, ss,
mid, st, si * 2 + 1)
+ constructSTUtil(arr, mid + 1,
se, st, si * 2 + 2);
return st[si];
}
// Function to construct a segment
// tree from given array. This
// function allocates memory for
// segment tree and calls
// constructSTUtil() to fill
// the allocated memory
int* constructST(int arr[], int n)
{
// Allocate memory for segment tree
// Height of segment tree
int x = (int)(ceil(log2(n)));
// Maximum size of segment tree
int max_size = 2 * (int)pow(2, x) - 1;
int* st = new int[max_size];
// Fill the allocated memory st
constructSTUtil(arr, 0, n - 1, st, 0);
// Return the constructed segment tree
return st;
}
// Driver Code
int main()
{
int arr[] = { 16, 15, 8, 9, 14, 25 };
int n = sizeof(arr) / sizeof(arr[0]);
// Build segment tree from given array
int* st = constructST(arr, n);
// Query 1: Query(start = 0, end = 4)
int start = 0;
int end = 4;
query(st, n, start, end);
// Query 2: Update(i = 3, x = 11),
// i.e Update a[i] to x
int i = 3;
int x = 11;
updateValue(arr, st, n, i, x);
// uncomment to see array after update
// for(int i = 0; i < n; i++)
// cout << arr[i] << " ";
// Query 3: Query(start = 0, end = 4)
start = 0;
end = 4;
query(st, n, start, end);
return 0;
}
Java
// Java program to find number of
// perfect square numbers in a
// subarray and performing updates
import java.util.*;
class GFG{
static final int MAX = 1000;
// Function to check if a number is
// a perfect square or not
static boolean isPerfectSquare(int x)
{
// Find floating point value of
// square root of x.
double sr = Math.sqrt(x);
// If square root is an integer
return ((sr - Math.floor(sr)) == 0) ?
true : false;
}
// A utility function to get
// the middle index from
// corner indexes.
static int getMid(int s,
int e)
{
return s + (e - s) / 2;
}
// Recursive function to get the number
// of perfect square numbers in a given
// range
/* where
st -. Pointer to segment tree
index -. Index of current node in the
segment tree. Initially 0 is
passed as root is always
at index 0
ss & se -. Starting and ending indexes
of the segment represented by
current node i.e. st[index]
qs & qe -. Starting and ending indexes
of query range */
static int queryUtil(int []st, int ss,
int se, int qs,
int qe, int index)
{
// If segment of this node is a part
// of given range, then return
// the number of perfect square numbers
// in the segment
if (qs <= ss && qe >= se)
return st[index];
// If segment of this node
// is outside the given range
if (se < qs || ss > qe)
return 0;
// If a part of this segment
// overlaps with the given range
int mid = getMid(ss, se);
return queryUtil(st, ss, mid, qs,
qe, 2 * index + 1) +
queryUtil(st, mid + 1, se,
qs, qe, 2 * index + 2);
}
// Recursive function to update
// the nodes which have the given
// index in their range.
/* where
st, si, ss & se are same as getSumUtil()
i -. index of the element to be updated.
This index is in input array.
diff -. Value to be added to all nodes
which have i in range
*/
static void updateValueUtil(int []st, int ss,
int se, int i,
int diff, int si)
{
// Base Case:
// If the input index lies outside
// the range of this segment
if (i < ss || i > se)
return;
// If the input index is in range
// of this node, then update the value
// of the node and its children
st[si] = st[si] + diff;
if (se != ss)
{
int mid = getMid(ss, se);
updateValueUtil(st, ss, mid, i,
diff, 2 * si + 1);
updateValueUtil(st, mid + 1, se,
i, diff, 2 * si + 2);
}
}
// Function to update a value in the
// input array and segment tree.
// It uses updateValueUtil() to update
// the value in segment tree
static void updateValue(int arr[], int[] st,
int n, int i,
int new_val)
{
// Check for erroneous
// input index
if (i < 0 || i > n - 1)
{
System.out.printf("Invalid Input");
return;
}
int diff = 0, oldValue;
oldValue = arr[i];
// Update the value in array
arr[i] = new_val;
// Case 1: Old and new values
// both are perfect square numbers
if (isPerfectSquare(oldValue) &&
isPerfectSquare(new_val))
return;
// Case 2: Old and new values
// both not perfect square numbers
if (!isPerfectSquare(oldValue) &&
!isPerfectSquare(new_val))
return;
// Case 3: Old value was perfect square,
// new value is not a perfect square
if (isPerfectSquare(oldValue) &&
!isPerfectSquare(new_val))
{
diff = -1;
}
// Case 4: Old value was
// non-perfect square,
// new_val is perfect square
if (!isPerfectSquare(oldValue) &&
!isPerfectSquare(new_val))
{
diff = 1;
}
// Update values of nodes
// in segment tree
updateValueUtil(st, 0, n - 1,
i, diff, 0);
}
// Return no. of perfect square numbers
// in range from index qs (query start)
// to qe (query end).
// It mainly uses queryUtil()
static void query(int[] st, int n,
int qs, int qe)
{
int perfectSquareInRange = queryUtil(st, 0,
n - 1,
qs, qe, 0);
System.out.print(perfectSquareInRange + "\n");
}
// Recursive function that constructs
// Segment Tree for array[ss..se].
// si is index of current node
// in segment tree st
static int constructSTUtil(int arr[], int ss,
int se, int []st, int si)
{
// If there is one element
// in array, check if it is
// perfect square number
// then store 1 in the
//segment tree else
// store 0 and return
if (ss == se)
{
// if arr[ss] is a perfect
// square number
if (isPerfectSquare(arr[ss]))
st[si] = 1;
else
st[si] = 0;
return st[si];
}
// If there are more than one
// elements, then recur for
// left and right subtrees
// and store the sum of the
// two values in this node
int mid = getMid(ss, se);
st[si] = constructSTUtil(arr, ss,
mid, st,
si * 2 + 1) +
constructSTUtil(arr, mid + 1,
se, st, si * 2 + 2);
return st[si];
}
// Function to cona segment
// tree from given array. This
// function allocates memory for
// segment tree and calls
// constructSTUtil() to fill
// the allocated memory
static int[] constructST(int arr[],
int n)
{
// Allocate memory for segment tree
// Height of segment tree
int x = (int)(Math.ceil(Math.log(n)));
// Maximum size of segment tree
int max_size = 4 * (int)Math.pow(2, x) + 1;
int []st = new int[max_size];
// Fill the allocated memory st
constructSTUtil(arr, 0, n - 1, st, 0);
// Return the constructed segment tree
return st;
}
// Driver Code
public static void main(String[] args)
{
int arr[] = {16, 15, 8, 9, 14, 25};
int n = arr.length;
// Build segment tree from
// given array
int []st = constructST(arr, n);
// Query 1: Query
// (start = 0, end = 4)
int start = 0;
int end = 4;
query(st, n, start, end);
// Query 2: Update(i = 3, x = 11),
// i.e Update a[i] to x
int i = 3;
int x = 11;
updateValue(arr, st, n, i, x);
// uncomment to see array after
// update for(int i = 0; i < n; i++)
// System.out.print(arr[i]+ " ");
// Query 3: Query(start = 0, end = 4)
start = 0;
end = 4;
query(st, n, start, end);
}
}
// This code is contributed by Rajput-Ji
Python3
# Python program to find number of
# perfect square numbers in a
# subarray and performing updates
from math import sqrt, floor, ceil, log2
from typing import List
MAX = 1000
# Function to check if a number is
# a perfect square or not
def isPerfectSquare(x: int) -> bool:
# Find floating point value of
# square root of x.
sr = sqrt(x)
# If square root is an integer
return True if ((sr - floor(sr)) == 0) else False
# A utility function to get the middle
# index from corner indexes.
def getMid(s: int, e: int) -> int:
return s + (e - s) // 2
# Recursive function to get the number
# of perfect square numbers in a given
# range
''' where
st --> Pointer to segment tree
index --> Index of current node in the
segment tree. Initially 0 is
passed as root is always
at index 0
ss & se --> Starting and ending indexes
of the segment represented by
current node i.e. st[index]
qs & qe --> Starting and ending indexes
of query range '''
def queryUtil(st: List[int], ss: int, se: int,
qs: int, qe: int,
index: int) -> int:
# If segment of this node is a part
# of given range, then return
# the number of perfect square numbers
# in the segment
if (qs <= ss and qe >= se):
return st[index]
# If segment of this node
# is outside the given range
if (se < qs or ss > qe):
return 0
# If a part of this segment
# overlaps with the given range
mid = getMid(ss, se)
return queryUtil(st, ss, mid, qs, qe, 2 * index + 1) + queryUtil(
st, mid + 1, se, qs, qe, 2 * index + 2)
# Recursive function to update
# the nodes which have the given
# index in their range.
''' where
st, si, ss & se are same as getSumUtil()
i --> index of the element to be updated.
This index is in input array.
diff --> Value to be added to all nodes
which have i in range
'''
def updateValueUtil(st: List[int], ss: int, se: int,
i: int, diff: int,
si: int) -> None:
# Base Case:
# If the input index lies outside
# the range of this segment
if (i < ss or i > se):
return
# If the input index is in range
# of this node, then update the value
# of the node and its children
st[si] = st[si] + diff
if (se != ss):
mid = getMid(ss, se)
updateValueUtil(st, ss, mid, i,
diff, 2 * si + 1)
updateValueUtil(st, mid + 1, se, i,
diff, 2 * si + 2)
# Function to update a value in the
# input array and segment tree.
# It uses updateValueUtil() to update
# the value in segment tree
def updateValue(arr: List[int], st: List[int],
n: int, i: int,
new_val: int) -> None:
# Check for erroneous input index
if (i < 0 or i > n - 1):
print("Invalid Input")
return
diff = 0
oldValue = 0
oldValue = arr[i]
# Update the value in array
arr[i] = new_val
# Case 1: Old and new values
# both are perfect square numbers
if (isPerfectSquare(oldValue) and isPerfectSquare(new_val)):
return
# Case 2: Old and new values
# both not perfect square numbers
if (not isPerfectSquare(oldValue) and not isPerfectSquare(new_val)):
return
# Case 3: Old value was perfect square,
# new value is not a perfect square
if (isPerfectSquare(oldValue) and not isPerfectSquare(new_val)):
diff = -1
# Case 4: Old value was
# non-perfect square,
# new_val is perfect square
if (not isPerfectSquare(oldValue) and not isPerfectSquare(new_val)):
diff = 1
# Update values of nodes in segment tree
updateValueUtil(st, 0, n - 1, i, diff, 0)
# Return no. of perfect square numbers
# in range from index qs (query start)
# to qe (query end).
# It mainly uses queryUtil()
def query(st: List[int], n: int, qs: int, qe: int) -> None:
perfectSquareInRange = queryUtil(st, 0, n - 1, qs, qe, 0)
print(perfectSquareInRange)
# Recursive function that constructs
# Segment Tree for array[ss..se].
# si is index of current node
# in segment tree st
def constructSTUtil(arr: List[int], ss: int, se: int, st: List[int],
si: int) -> int:
# If there is one element in array,
# check if it is perfect square number
# then store 1 in the segment tree
# else store 0 and return
if (ss == se):
# if arr[ss] is a perfect
# square number
if (isPerfectSquare(arr[ss])):
st[si] = 1
else:
st[si] = 0
return st[si]
# If there are more than one
# elements, then recur for
# left and right subtrees
# and store the sum of the
# two values in this node
mid = getMid(ss, se)
st[si] = constructSTUtil(arr, ss, mid, st, si * 2 + 1) + constructSTUtil(
arr, mid + 1, se, st, si * 2 + 2)
return st[si]
# Function to construct a segment
# tree from given array. This
# function allocates memory for
# segment tree and calls
# constructSTUtil() to fill
# the allocated memory
def constructST(arr: List[int], n: int) -> List[int]:
# Allocate memory for segment tree
# Height of segment tree
x = (ceil(log2(n)))
# Maximum size of segment tree
max_size = 2 * pow(2, x) - 1
st = [0 for _ in range(max_size)]
# Fill the allocated memory st
constructSTUtil(arr, 0, n - 1, st, 0)
# Return the constructed segment tree
return st
# Driver Code
if __name__ == "__main__":
arr = [16, 15, 8, 9, 14, 25]
n = len(arr)
# Build segment tree from given array
st = constructST(arr, n)
# Query 1: Query(start = 0, end = 4)
start = 0
end = 4
query(st, n, start, end)
# Query 2: Update(i = 3, x = 11),
# i.e Update a[i] to x
i = 3
x = 11
updateValue(arr, st, n, i, x)
# uncomment to see array after update
# for(int i = 0; i < n; i++)
# cout << arr[i] << " ";
# Query 3: Query(start = 0, end = 4)
start = 0
end = 4
query(st, n, start, end)
# This code is contributed by sanjeev2552
C#
// C# program to find number of
// perfect square numbers in a
// subarray and performing updates
using System;
class GFG{
static readonly int MAX = 1000;
// Function to check if a number
// is a perfect square or not
static bool isPerfectSquare(int x)
{
// Find floating point value of
// square root of x.
double sr = Math.Sqrt(x);
// If square root is an integer
return ((sr - Math.Floor(sr)) == 0) ?
true : false;
}
// A utility function to get
// the middle index from
// corner indexes.
static int getMid(int s,
int e)
{
return s + (e - s) / 2;
}
// Recursive function to get the number
// of perfect square numbers in a given
// range
/* where
st -. Pointer to segment tree
index -. Index of current node in the
segment tree. Initially 0 is
passed as root is always
at index 0
ss & se -. Starting and ending indexes
of the segment represented by
current node i.e. st[index]
qs & qe -. Starting and ending indexes
of query range */
static int queryUtil(int []st, int ss,
int se, int qs,
int qe, int index)
{
// If segment of this node is a part
// of given range, then return the
// number of perfect square numbers
// in the segment
if (qs <= ss && qe >= se)
return st[index];
// If segment of this node
// is outside the given range
if (se < qs || ss > qe)
return 0;
// If a part of this segment
// overlaps with the given range
int mid = getMid(ss, se);
return queryUtil(st, ss, mid, qs,
qe, 2 * index + 1) +
queryUtil(st, mid + 1, se,
qs, qe, 2 * index + 2);
}
// Recursive function to update
// the nodes which have the given
// index in their range.
/* where
st, si, ss & se are same as getSumUtil()
i -. index of the element to be updated.
This index is in input array.
diff -. Value to be added to all nodes
which have i in range
*/
static void updateValueUtil(int []st, int ss,
int se, int i,
int diff, int si)
{
// Base Case:
// If the input index lies outside
// the range of this segment
if (i < ss || i > se)
return;
// If the input index is in range
// of this node, then update the value
// of the node and its children
st[si] = st[si] + diff;
if (se != ss)
{
int mid = getMid(ss, se);
updateValueUtil(st, ss, mid, i,
diff, 2 * si + 1);
updateValueUtil(st, mid + 1, se,
i, diff, 2 * si + 2);
}
}
// Function to update a value in the
// input array and segment tree.
// It uses updateValueUtil() to update
// the value in segment tree
static void updateValue(int []arr, int[] st,
int n, int i,
int new_val)
{
// Check for erroneous
// input index
if (i < 0 || i > n - 1)
{
Console.Write("Invalid Input");
return;
}
int diff = 0, oldValue;
oldValue = arr[i];
// Update the value in array
arr[i] = new_val;
// Case 1: Old and new values
// both are perfect square numbers
if (isPerfectSquare(oldValue) &&
isPerfectSquare(new_val))
return;
// Case 2: Old and new values
// both not perfect square numbers
if (!isPerfectSquare(oldValue) &&
!isPerfectSquare(new_val))
return;
// Case 3: Old value was perfect
// square, new value is not a
// perfect square
if (isPerfectSquare(oldValue) &&
!isPerfectSquare(new_val))
{
diff = -1;
}
// Case 4: Old value was
// non-perfect square,
// new_val is perfect square
if (!isPerfectSquare(oldValue) &&
!isPerfectSquare(new_val))
{
diff = 1;
}
// Update values of nodes
// in segment tree
updateValueUtil(st, 0, n - 1,
i, diff, 0);
}
// Return no. of perfect square numbers
// in range from index qs (query start)
// to qe (query end).
// It mainly uses queryUtil()
static void query(int[] st, int n,
int qs, int qe)
{
int perfectSquareInRange = queryUtil(st, 0,
n - 1,
qs, qe, 0);
Console.Write(perfectSquareInRange + "\n");
}
// Recursive function that constructs
// Segment Tree for array[ss..se].
// si is index of current node
// in segment tree st
static int constructSTUtil(int []arr, int ss,
int se, int []st, int si)
{
// If there is one element
// in array, check if it is
// perfect square number
// then store 1 in the
//segment tree else
// store 0 and return
if (ss == se)
{
// if arr[ss] is a perfect
// square number
if (isPerfectSquare(arr[ss]))
st[si] = 1;
else
st[si] = 0;
return st[si];
}
// If there are more than one
// elements, then recur for
// left and right subtrees
// and store the sum of the
// two values in this node
int mid = getMid(ss, se);
st[si] = constructSTUtil(arr, ss,
mid, st,
si * 2 + 1) +
constructSTUtil(arr, mid + 1,
se, st, si * 2 + 2);
return st[si];
}
// Function to cona segment
// tree from given array. This
// function allocates memory for
// segment tree and calls
// constructSTUtil() to fill
// the allocated memory
static int[] constructST(int []arr,
int n)
{
// Allocate memory for segment tree
// Height of segment tree
int x = (int)(Math.Ceiling(Math.Log(n)));
// Maximum size of segment tree
int max_size = 4 * (int)Math.Pow(2,
x) + 1;
int []st = new int[max_size];
// Fill the allocated
// memory st
constructSTUtil(arr, 0,
n - 1,
st, 0);
// Return the constructed
// segment tree
return st;
}
// Driver Code
public static void Main(String[] args)
{
int []arr = {16, 15, 8, 9, 14, 25};
int n = arr.Length;
// Build segment tree
// from given array
int []st = constructST(arr, n);
// Query 1: Query
// (start = 0, end = 4)
int start = 0;
int end = 4;
query(st, n, start, end);
// Query 2: Update(i = 3,
// x = 11), i.e Update a[i] to x
int i = 3;
int x = 11;
updateValue(arr, st, n, i, x);
// uncomment to see array after
// update for(int i = 0; i < n; i++)
// Console.Write(arr[i]+ " ");
// Query 3: Query(start = 0,
// end = 4)
start = 0;
end = 4;
query(st, n, start, end);
}
}
// This code is contributed by Rajput-Ji
2
1
时间复杂度:每个查询和更新的时间复杂度为O(log N) ,构建段树的时间复杂度为O(N)