📌  相关文章
📜  查询更新范围为[L,R]的数组元素以满足给定条件

📅  最后修改于: 2021-05-14 02:32:48             🧑  作者: Mango

给定由N 0 s组成的数组arr []和形式为(L,R)的每一行的数组Q [] [] ,每个查询的任务是更新[L, R] ,使得arr [i] = i – L + 1

例子:

天真的方法:解决问题的最简单方法是遍历数组Q [] [] ,对于每个查询,遍历给定范围内的所有数组元素并更新arr [i] + = i – L + 1 。最后,打印数组元素。
时间复杂度: O(N * Q)
辅助空间: O(1)

高效方法:可以使用差分数组的概念来优化上述方法。请按照以下步骤解决问题:

  • 初始化两个数组arr1 []arr2 []并将所有元素初始化为0
  • 遍历查询数组Q [] [] 。对于(L,R)类型的每个查询,更新arr1 [L] + = 1arr1 [R + 1]-= 1arr2 [R +1]-= R – L + 1
  • 遍历数组,ARR1 []并存储ARR1的前缀总和[],ARR1 [I] + = ARR1 [I-1]。
  • 遍历数组arr2 []并更新arr2 [i] + = arr2 [i – 1] + arr1 [i]
  • 最后,打印数组arr2 []

下面是上述方法的实现:

C++
// C++ program to implement
// the above approach
#include 
using namespace std;
 
// Function to print the array
void printArray(int arr[], int N)
{
    for (int i = 0; i < N; i++) {
        cout << arr[i] << " ";
    }
}
 
// Function to perfrom the query in range [L, R]
// such that arr[i] += i - L + 1
void modifyArray(int arr[], int N, int Q[][2],
                 int cntQuery)
{
 
    // Initialize array
    int arr1[N + 1] = { 0 };
    int arr2[N + 1] = { 0 };
 
    // Traverse the query array
    for (int i = 0; i < cntQuery; i++) {
 
        // Stores range in 1-based index
        int L = Q[i][0] + 1, R = Q[i][1] + 1;
 
        // Update arr1[L]
        arr1[L]++;
 
        // Update arr1[R + 1]
        arr1[R + 1]--;
 
        // Update arr2[R + 1]
        arr2[R + 1] -= R - L + 1;
    }
 
    // Calculate prefix sum
    for (int i = 1; i <= N; i++)
        arr1[i] += arr1[i - 1];
 
    // Traverse the array, arr2[]
    for (int i = 1; i <= N; i++)
        arr2[i] += arr2[i - 1] + arr1[i];
 
    // Copy arr2[] into arr[]
    for (int i = 1; i <= N; i++)
        arr[i - 1] = arr2[i];
 
    printArray(arr, N);
}
 
// Driver Code
int main()
{
    // Given array
    int arr[] = { 0, 0, 0, 0 };
 
    // Size of the array
    int N = sizeof(arr) / sizeof(arr[0]);
 
    int Q[][2] = { { 1, 3 }, { 0, 1 } };
 
    // Stores count of query
    int cntQuery
        = sizeof(Q) / sizeof(Q[0]);
 
    // Function Call
    modifyArray(arr, N, Q, cntQuery);
 
    return 0;
}


Java
// Java program to implement
// the above approach
class GFG
{
 
    // Function to print the array
    static void printArray(int arr[], int N)
    {
        for (int i = 0; i < N; i++)
        {
            System.out.print(arr[i] + " ");
        }
    }
     
    // Function to perfrom the query in range [L, R]
    // such that arr[i] += i - L + 1
    static void modifyArray(int arr[], int N, int Q[][],
                     int cntQuery)
    {
     
        // Initialize array
        int arr1[] = new int[N + 2];
        int arr2[] = new int[N + 2];
     
        // Traverse the query array
        for (int i = 0; i < cntQuery; i++)
        {
     
            // Stores range in 1-based index
            int L = Q[i][0] + 1, R = Q[i][1] + 1;
     
            // Update arr1[L]
            arr1[L]++;
     
            // Update arr1[R + 1]
            arr1[R + 1]--;
     
            // Update arr2[R + 1]
            arr2[R + 1] -= R - L + 1;
        }
     
        // Calculate prefix sum
        for (int i = 1; i <= N; i++)
            arr1[i] += arr1[i - 1];
     
        // Traverse the array, arr2[]
        for (int i = 1; i <= N; i++)
            arr2[i] += arr2[i - 1] + arr1[i];
     
        // Copy arr2[] into arr[]
        for (int i = 1; i <= N; i++)
            arr[i - 1] = arr2[i];   
        printArray(arr, N);
    }
     
    // Driver Code
    public static void main (String[] args)
    {
       
        // Given array
        int arr[] = { 0, 0, 0, 0 };
     
        // Size of the array
        int N = arr.length;   
        int Q[][] = { { 1, 3 }, { 0, 1 } };
     
        // Stores count of query
        int cntQuery = Q.length;
     
        // Function Call
        modifyArray(arr, N, Q, cntQuery);
    }
}
 
// This code is contributed by AnkThon


Python3
# Python3 program to implement
# the above approach
 
# Function to prthe array
def printArray(arr, N):
    print(*arr)
 
# Function to perfrom the query in range [L, R]
# such that arr[i] += i - L + 1
def modifyArray(arr, N, Q, cntQuery):
 
    # Initialize array
    arr1 = [0 for i in range(N + 2)]
    arr2 = [0 for i in range(N + 2)]
 
    # Traverse the query array
    for i in range(cntQuery):
 
        # Stores range in 1-based index
        L = Q[i][0] + 1
        R = Q[i][1] + 1
        # print(L,R)
 
        # Update arr1[L]
        arr1[L] += 1
 
        # Update arr1[R + 1]
        arr1[R + 1] -= 1
 
        # Update arr2[R + 1]
        arr2[R + 1] -= R - L + 1
 
    # Calculate prefix sum
    for i in range(1, N + 1):
        arr1[i] += arr1[i - 1]
 
    # Traverse the array, arr2[]
    for i in range(1, N + 1):
        arr2[i] += arr2[i - 1] + arr1[i]
 
    # Copy arr2[] into arr[]
    for i in range(1, N + 1):
        arr[i - 1] = arr2[i]
    printArray(arr, N)
 
# Driver Code
if __name__ == '__main__':
     
    # Given array
    arr = [0, 0, 0, 0]
 
    # Size of the array
    N = len(arr)
    Q = [[ 1, 3 ], [ 0, 1 ]]
 
    # Stores count of query
    cntQuery = len(Q)
 
    # Function Call
    modifyArray(arr, N, Q, cntQuery)
 
# This code is contributed by mohit kumar 29.


C#
// C# program to implement
// the above approach
using System;
class GFG
{
 
    // Function to print the array
    static void printArray(int []arr, int N)
    {
        for (int i = 0; i < N; i++)
        {
            Console.Write(arr[i] + " ");
        }
    }
     
    // Function to perfrom the query in range [L, R]
    // such that arr[i] += i - L + 1
    static void modifyArray(int []arr, int N, int[,] Q,
                     int cntQuery)
    {
     
        // Initialize array
        int []arr1 = new int[N + 2];
        int []arr2 = new int[N + 2];
     
        // Traverse the query array
        for (int i = 0; i < cntQuery; i++)
        {
     
            // Stores range in 1-based index
            int L = Q[i,0] + 1, R = Q[i,1] + 1;
     
            // Update arr1[L]
            arr1[L]++;
     
            // Update arr1[R + 1]
            arr1[R + 1]--;
     
            // Update arr2[R + 1]
            arr2[R + 1] -= R - L + 1;
        }
     
        // Calculate prefix sum
        for (int i = 1; i <= N; i++)
            arr1[i] += arr1[i - 1];
     
        // Traverse the array, arr2[]
        for (int i = 1; i <= N; i++)
            arr2[i] += arr2[i - 1] + arr1[i];
     
        // Copy arr2[] into arr[]
        for (int i = 1; i <= N; i++)
            arr[i - 1] = arr2[i];   
        printArray(arr, N);
    }
     
    // Driver Code
    public static void Main()
    {
       
        // Given array
        int []arr = { 0, 0, 0, 0 };
     
        // Size of the array
        int N = arr.Length;   
        int [,]Q = { { 1, 3 }, { 0, 1 } };
     
        // Stores count of query
        int cntQuery = 2;
     
        // Function Call
        modifyArray(arr, N, Q, cntQuery);
    }
}
 
// This code is contributed by bgangwar59.


输出:
1 3 2 3

时间复杂度: O(N + Q)
辅助空间: O(N)