Queries to update array elements in a range [L, R] to satisfy given conditions
Given an array arr[] consisting of N 0s and an array Q[][] with each row of the form (L, R)., the task for each query is to update all the array elements in the range [L, R] such that arr[i] = i – L + 1.
Examples:
Input: arr[] = { 0, 0, 0, 0 }, Q[][] = { { 1, 2 }, { 0, 1 } }
Output: 1 3 2 0
Explanation:
Query1: Updating arr[1] = 1 – 1 + 1, arr[2] = 2 – 1 + 1 modifies arr[] to { 0, 1, 2, 0 }
Query2: Updating arr[0] = 0 – 0 + 1, arr[1] = 1 – 0 + 1 modifies arr[] to { 1, 3, 2, 0 }
Therefore, the required output is 1 3 2 0.Input: arr[] = { 0, 0, 0, 0 }, Q[][] = { { 1, 3 }, { 0, 1 } }
Output: 1 3 2 3
Naive Approach:The simplest approach to solve the problem is to traverse the array Q[][] and for each query, traverse all the array elements in the given range and update arr[i] += i – L + 1. Finally, print the array elements.
Time Complexity: O(N * Q)
Auxiliary Space: O(1)
Efficient Approach: The above approach can be optimized using the concept of Difference Array. Follow the steps below to solve the problem:
- Initialize two arrays arr1[] and arr2[] and initialize all elements as 0.
- Traverse the query array, Q[][]. For each query of type (L, R) update arr1[L] += 1, arr1[R + 1] -= 1 and arr2[R + 1] -= R – L + 1.
- Traverse the array, arr1[] and store the prefix sum of arr1[], i.e. arr1[i] += arr1[i -1].
- Traverse the array, arr2[] and update arr2[i] += arr2[i – 1] + arr1[i].
- Finally, print the array, arr2[].
Below is the implementation of the above approach:
C++
// C++ program to implement // the above approach #include <bits/stdc++.h> 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 perform 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 perform 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 print array def printArray(arr, N): print ( * arr) # Function to perform 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 perform 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. |
Javascript
<script> // Javascript program to implement // the above approach // Function to print the array function printArray(arr, N) { for (let i = 0; i < N; i++) { document.write(arr[i] + " " ); } } // Function to perform the query in // range [L, R] such that // arr[i] += i - L + 1 function modifyArray(arr, N, Q, cntQuery) { // Initialize array let arr1 = new Array(N + 2).fill(0); let arr2 = new Array(N + 2).fill(0); // Traverse the query array for (let i = 0; i < cntQuery; i++) { // Stores range in 1-based index let 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 (let i = 1; i <= N; i++) arr1[i] += arr1[i - 1]; // Traverse the array, arr2[] for (let i = 1; i <= N; i++) arr2[i] += arr2[i - 1] + arr1[i]; // Copy arr2[] into arr[] for (let i = 1; i <= N; i++) arr[i - 1] = arr2[i]; prletArray(arr, N); } // Driver Code // Given array let arr = [ 0, 0, 0, 0 ]; // Size of the array let N = arr.length; let Q = [ [ 1, 3 ], [ 0, 1 ] ]; // Stores count of query let cntQuery = Q.length; // Function Call modifyArray(arr, N, Q, cntQuery); // This code is contributed by avijitmondal1998 </script> |
1 3 2 3
Time Complexity: O(N+Q)
Auxiliary Space: O(N)
Please Login to comment...