给定一个由N 0 个组成的数组arr[]和一个由以下两种类型的查询组成的二维数组Q[][] :
- 1 LRX:将[L, R]范围内的所有元素增加X 。
- 2 X:在数组的第X个索引处打印元素。
Input: arr[] = { 0, 0, 0, 0, 0 }, Q[][] = { { 1, 0, 2, 100 }, { 2, 1 }, { 1, 2, 3, 200 }, { 2, 2 }, {
4 } }
Output: 100 300 0
Explanation:
Query1: Incrementing all the array elements in the range [0, 2] by 100 modifies arr[] to { 100, 100, 100, 0, 0 }.
Query2: Print arr[1](=100)
Query3: Incrementing all the array elements in the range [2, 3] by 200 modifies arr[] to { 100, 100, 300, 200, 0 }.
Query4: Print arr[2](=300)
Query5: Print arr[4](=0)
Input: arr[] = { 0, 0 }, Q[][] = { { 1, 0, 1, 100 }, { 2, 1 } }
Output: 100
方法:思路是利用 Segment Tree 的概念来执行类型2 的查询,使用差异数组来执行类型1 的查询。请按照以下步骤解决问题:
- 对于{ 1, L, R, X }类型的查询,使用 Segment 树更新arr[L] += X和arr[R + 1] -= X。
- 对于{2, X}类型的查询,使用 Segment Tree 查找[0, X]范围内数组元素的总和并打印获得的总和。
下面是上述方法的实现:
C++
// C++ program to implement
// the above approach
#include
using namespace std;
// Function to update the array elements
// at idx pos, i.e arr[pos] += X
void update(int Tree[], int idx, int s,
int e, int pos, int X)
{
// If current node is a
// leaf nodes
if (s == e) {
// Update Tree[idx]
Tree[idx] += X;
}
else {
// Divide segment tree into left
// and right subtree
int m = (s + e) / 2;
// Check if pos lies in left subtree
if (pos <= m) {
// Seach pos in left subtree
update(Tree, 2 * idx, s, m, pos, X);
}
else {
// Search pos in right subtree
update(Tree, 2 * idx + 1, m + 1, e,
pos, X);
}
// Update Tree[idx]
Tree[idx]
= Tree[2 * idx] + Tree[2 * idx + 1];
}
}
// Function to find the sum from
// elements in the range [0, X]
int sum(int Tree[], int idx, int s,
int e, int ql, int qr)
{
// Check if range[ql, qr] equals
// to range [s, e]
if (ql == s && qr == e)
return Tree[idx];
if (ql > qr)
return 0;
// Divide segment tree into
// left substree and
// right substree
int m = (s + e) / 2;
// Return sum of elements in the range[ql, qr]
return sum(Tree, 2 * idx, s, m, ql, min(m, qr))
+ sum(Tree, 2 * idx + 1, m + 1, e,
max(ql, m + 1), qr);
}
// Function to find Xth element
// in the array
void getElement(int Tree[], int X, int N)
{
// Print element at index x
cout << "Element at " << X << " is "
<< sum(Tree, 1, 0, N - 1, 0, X) << endl;
}
// Function to update array elements
// in the range [L, R]
void range_Update(int Tree[], int L,
int R, int X, int N)
{
// Update arr[l] += X
update(Tree, 1, 0, N - 1, L, X);
// Update arr[R + 1] += X
if (R + 1 < N)
update(Tree, 1, 0, N - 1, R + 1, -X);
}
// Drivers Code
int main()
{
// Size of array
int N = 5;
int Tree[4 * N + 5] = { 0 };
int arr[] = { 0, 0 };
vector >
Q = { { 1, 0, 1, 100 }, { 2, 1 } };
int cntQuery = Q.size();
for (int i = 0; i < cntQuery; i++) {
if (Q[i][0] == 1) {
range_Update(Tree, Q[i][1],
Q[i][2], Q[i][3], N);
}
else {
getElement(Tree, Q[i][1], N);
}
}
}
Java
// Java program to implement
// the above approach
import java.util.*;
class GFG
{
// Function to update the array elements
// at idx pos, i.e arr[pos] += X
static void update(int Tree[], int idx, int s,
int e, int pos, int X)
{
// If current node is a
// leaf nodes
if (s == e)
{
// Update Tree[idx]
Tree[idx] += X;
}
else
{
// Divide segment tree into left
// and right subtree
int m = (s + e) / 2;
// Check if pos lies in left subtree
if (pos <= m)
{
// Seach pos in left subtree
update(Tree, 2 * idx, s, m, pos, X);
}
else
{
// Search pos in right subtree
update(Tree, 2 * idx + 1, m + 1, e,
pos, X);
}
// Update Tree[idx]
Tree[idx]
= Tree[2 * idx] + Tree[2 * idx + 1];
}
}
// Function to find the sum from
// elements in the range [0, X]
static int sum(int Tree[], int idx, int s,
int e, int ql, int qr)
{
// Check if range[ql, qr] equals
// to range [s, e]
if (ql == s && qr == e)
return Tree[idx];
if (ql > qr)
return 0;
// Divide segment tree into
// left substree and
// right substree
int m = (s + e) / 2;
// Return sum of elements in the range[ql, qr]
return sum(Tree, 2 * idx, s, m, ql, Math.min(m, qr))
+ sum(Tree, 2 * idx + 1, m + 1, e,
Math.max(ql, m + 1), qr);
}
// Function to find Xth element
// in the array
static void getElement(int Tree[], int X, int N)
{
// Print element at index x
System.out.print("Element at " + X+ " is "
+ sum(Tree, 1, 0, N - 1, 0, X) +"\n");
}
// Function to update array elements
// in the range [L, R]
static void range_Update(int Tree[], int L,
int R, int X, int N)
{
// Update arr[l] += X
update(Tree, 1, 0, N - 1, L, X);
// Update arr[R + 1] += X
if (R + 1 < N)
update(Tree, 1, 0, N - 1, R + 1, -X);
}
// Drivers Code
public static void main(String[] args)
{
// Size of array
int N = 5;
int Tree[] = new int[4 * N + 5];
int arr[] = { 0, 0 };
int[][]
Q = { { 1, 0, 1, 100 }, { 2, 1 } };
int cntQuery = Q.length;
for (int i = 0; i < cntQuery; i++)
{
if (Q[i][0] == 1)
{
range_Update(Tree, Q[i][1],
Q[i][2], Q[i][3], N);
}
else
{
getElement(Tree, Q[i][1], N);
}
}
}
}
// This code is contributed by shikhasingrajput
Python3
# Python3 program to implement
# the above approach
# Function to update the array elements
# at idx pos, i.e arr[pos] += X
def update(Tree, idx, s, e, pos, X):
# If current node is a
# leaf nodes
if (s == e):
# Update Tree[idx]
Tree[idx] += X
else:
# Divide segment tree into left
# and right subtree
m = (s + e) // 2
# Check if pos lies in left subtree
if (pos <= m):
# Seach pos in left subtree
update(Tree, 2 * idx, s, m, pos, X)
else:
# Search pos in right subtree
update(Tree, 2 * idx + 1, m + 1, e,pos, X)
# Update Tree[idx]
Tree[idx] = Tree[2 * idx] + Tree[2 * idx + 1]
# Function to find the sum from
# elements in the range [0, X]
def sum(Tree, idx, s, e, ql, qr):
# Check if range[ql, qr] equals
# to range [s, e]
if (ql == s and qr == e):
return Tree[idx]
if (ql > qr):
return 0
# Divide segment tree into
# left substree and
# right substree
m = (s + e) // 2
# Return sum of elements in the range[ql, qr]
return sum(Tree, 2 * idx, s, m, ql, min(m, qr))+ sum(Tree, 2 * idx + 1, m + 1, e,max(ql, m + 1), qr)
# Function to find Xth element
# in the array
def getElement(Tree, X, N):
# Prelement at index x
print("Element at", X, "is ", sum(Tree, 1, 0, N - 1, 0, X))
# Function to update array elements
# in the range [L, R]
def range_Update(Tree, L, R, X, N):
# Update arr[l] += X
update(Tree, 1, 0, N - 1, L, X)
# Update arr[R + 1] += X
if (R + 1 < N):
update(Tree, 1, 0, N - 1, R + 1, -X)
# Drivers Code
if __name__ == '__main__':
# Size of array
N = 5
Tree = [0]*(4 * N + 5)
arr = [0, 0]
Q = [ [1, 0, 1, 100], [2, 1] ]
cntQuery = len(Q)
for i in range(cntQuery):
if (Q[i][0] == 1):
range_Update(Tree, Q[i][1], Q[i][2], Q[i][3], N)
else:
getElement(Tree, Q[i][1], N)
# This code is contributed by mohit kumar 29.
C#
// C# program to implement
// the above approach
using System;
public class GFG
{
// Function to update the array elements
// at idx pos, i.e arr[pos] += X
static void update(int []Tree, int idx, int s,
int e, int pos, int X)
{
// If current node is a
// leaf nodes
if (s == e)
{
// Update Tree[idx]
Tree[idx] += X;
}
else
{
// Divide segment tree into left
// and right subtree
int m = (s + e) / 2;
// Check if pos lies in left subtree
if (pos <= m)
{
// Seach pos in left subtree
update(Tree, 2 * idx, s, m, pos, X);
}
else
{
// Search pos in right subtree
update(Tree, 2 * idx + 1, m + 1, e,
pos, X);
}
// Update Tree[idx]
Tree[idx]
= Tree[2 * idx] + Tree[2 * idx + 1];
}
}
// Function to find the sum from
// elements in the range [0, X]
static int sum(int []Tree, int idx, int s,
int e, int ql, int qr)
{
// Check if range[ql, qr] equals
// to range [s, e]
if (ql == s && qr == e)
return Tree[idx];
if (ql > qr)
return 0;
// Divide segment tree into
// left substree and
// right substree
int m = (s + e) / 2;
// Return sum of elements in the range[ql, qr]
return sum(Tree, 2 * idx, s, m, ql, Math.Min(m, qr))
+ sum(Tree, 2 * idx + 1, m + 1, e,
Math.Max(ql, m + 1), qr);
}
// Function to find Xth element
// in the array
static void getElement(int []Tree, int X, int N)
{
// Print element at index x
Console.Write("Element at " + X+ " is "
+ sum(Tree, 1, 0, N - 1, 0, X) +"\n");
}
// Function to update array elements
// in the range [L, R]
static void range_Update(int []Tree, int L,
int R, int X, int N)
{
// Update arr[l] += X
update(Tree, 1, 0, N - 1, L, X);
// Update arr[R + 1] += X
if (R + 1 < N)
update(Tree, 1, 0, N - 1, R + 1, -X);
}
// Drivers Code
public static void Main(String[] args)
{
// Size of array
int N = 5;
int []Tree = new int[4 * N + 5];
int []arr = { 0, 0 };
int[,]Q = { { 1, 0, 1, 100 }, { 2, 1, 0, 0 } };
int cntQuery = Q.GetLength(0);
for (int i = 0; i < cntQuery; i++)
{
if (Q[i, 0] == 1)
{
range_Update(Tree, Q[i, 1],
Q[i, 2], Q[i, 3], N);
}
else
{
getElement(Tree, Q[i, 1], N);
}
}
}
}
// This code is contributed by 29AjayKumar
Javascript
Element at 1 is 100
时间复杂度: O(|Q| * log(N))
辅助空间: O(N)
如果您想与行业专家一起参加直播课程,请参阅Geeks Classes Live