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++ 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 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 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# 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. |
<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)