对数组进行恒定时间范围添加操作
给定一个大小为 N 的数组,该数组初始化为全零。我们得到了许多范围添加查询,这些查询应该应用于这个数组。我们需要打印最终更新的数组作为我们的结果。
例子:
N = 6
Arr = [0, 0, 0, 0, 0, 0]
rangeUpdate1 [0, 2], add 100
Arr = [100, 100, 100, 0, 0, 0]
rangeUpdate1 [1, 5], add 100
Arr = [100, 200, 200, 100, 100, 100]
rangeUpdate1 [2, 3], add 100
Arr = [100, 200, 300, 200, 100, 100]
Which is the final updated array.
这个问题可以使用分段树来解决,每个查询在 O(log N) 时间内进行延迟更新,但我们可以在这里做得更好,因为没有给出更新操作。当在范围 [a, b] 中给出要添加 V 的查询时,我们可以使用此逻辑在恒定时间内处理每个查询,如果我们愿意,现在我们将添加 V 到 arr[a] 和 -V 到 arr[b+1]获取数组的实际值,我们将上面的数组转换为前缀和数组。
请参阅下面的示例以了解:
Arr = [0, 0, 0, 0, 0, 0]
rangeUpdate1 [0, 2], add 100
Arr = [100, 0, 0, -100, 0, 0]
rangeUpdate1 [1, 5], add 100.
Arr = [100, 100, 0, -100, 0, 0]
Note: You can not add -100 at 6th index because array length is 6.
rangeUpdate1 [2, 3], add 100
Arr = [100, 100, 100, -100, -100, 0]
Now we will convert above operation array to prefix sum array as shown below,
Arr = [100, 200, 300, 200, 100, 100]
Which is the final updated array.
所以实际上,当我们为数组的特定索引添加一个值V时,它表示将V添加到该索引的所有元素,这就是为什么我们在range之后添加-V以在其添加查询的范围之后消除它的影响。
请注意,在下面的代码中,如果范围跨越到最后一个索引,则省略 -V 的添加以处于数组的内存限制中。
C++
// C++ program to get updated array after many array range
// add operation
#include
using namespace std;
// Utility method to add value val, to range [lo, hi]
void add(int arr[], int N, int lo, int hi, int val)
{
arr[lo] += val;
if (hi != N - 1)
arr[hi + 1] -= val;
}
// Utility method to get actual array from operation array
void updateArray(int arr[], int N)
{
// convert array into prefix sum array
for (int i = 1; i < N; i++)
arr[i] += arr[i - 1];
}
// method to print final updated array
void printArr(int arr[], int N)
{
updateArray(arr, N);
for (int i = 0; i < N; i++)
cout << arr[i] << " ";
cout << endl;
}
// Driver code
int main()
{
int N = 6;
int arr[N] = {0};
// Range add Queries
add(arr, N, 0, 2, 100);
add(arr, N, 1, 5, 100);
add(arr, N, 2, 3, 100);
printArr(arr, N);
return 0;
}
Java
// Java program to get updated array after
// many array range add operation
import java.io.*;
class GFG {
// Utility method to add value val,
// to range [lo, hi]
static void add(int arr[], int N, int lo, int hi,
int val)
{
arr[lo] += val;
if (hi != N - 1)
arr[hi + 1] -= val;
}
// Utility method to get actual array from
// operation array
static void updateArray(int arr[], int N)
{
// convert array into prefix sum array
for (int i = 1; i < N; i++)
arr[i] += arr[i - 1];
}
// method to print final updated array
static void printArr(int arr[], int N)
{
updateArray(arr, N);
for (int i = 0; i < N; i++)
System.out.print("" + arr[i] + " ");
System.out.print("\n");
}
// Driver code
public static void main(String[] args)
{
int N = 6;
int arr[] = new int[N];
// Range add Queries
add(arr, N, 0, 2, 100);
add(arr, N, 1, 5, 100);
add(arr, N, 2, 3, 100);
printArr(arr, N);
}
}
// This code is contributed by Prakriti Gupta
Python3
# Python3 program to get updated array
# after many array range add operation
# Utility method to add value
# val, to range [lo, hi]
def add(arr, N, lo, hi, val):
arr[lo] += val
if (hi != N - 1):
arr[hi + 1] -= val
# Utility method to get actual
# array from operation array
def updateArray(arr, N):
# convert array into prefix sum array
for i in range(1, N):
arr[i] += arr[i - 1]
# method to print final updated array
def printArr(arr, N):
updateArray(arr, N)
for i in range(N):
print(arr[i], end=" ")
print()
# Driver code
N = 6
arr = [0 for i in range(N)]
# Range add Queries
add(arr, N, 0, 2, 100)
add(arr, N, 1, 5, 100)
add(arr, N, 2, 3, 100)
printArr(arr, N)
# This code is contributed by Anant Agarwal.
C#
// C# program to get updated array after
// many array range add operation
using System;
class GFG {
// Utility method to add value val,
// to range [lo, hi]
static void add(int[] arr, int N, int lo, int hi,
int val)
{
arr[lo] += val;
if (hi != N - 1)
arr[hi + 1] -= val;
}
// Utility method to get actual
// array from operation array
static void updateArray(int[] arr, int N)
{
// convert array into
// prefix sum array
for (int i = 1; i < N; i++)
arr[i] += arr[i - 1];
}
// method to print final updated array
static void printArr(int[] arr, int N)
{
updateArray(arr, N);
for (int i = 0; i < N; i++)
Console.Write("" + arr[i] + " ");
Console.Write("\n");
}
// Driver code
public static void Main()
{
int N = 6;
int[] arr = new int[N];
// Range add Queries
add(arr, N, 0, 2, 100);
add(arr, N, 1, 5, 100);
add(arr, N, 2, 3, 100);
printArr(arr, N);
}
}
// This code is contributed by Nitin Mittal.
PHP
Javascript
输出
100 200 300 200 100 100