📌  相关文章
📜  对数组进行恒定时间范围添加操作

📅  最后修改于: 2022-05-13 01:57:51.752000             🧑  作者: Mango

对数组进行恒定时间范围添加操作

给定一个大小为 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