Given an array, arr[] of N positive integers and M queries of the form {a, b, val, f}. The task is to print the array after performing each query to increment array elements in the range [a, b] by a value val f number of times.
Examples:
Input: arr[] = {1, 2, 3}, M=3, Q[][] = {{1, 2, 1, 4}, {1, 3, 2, 3}, {2, 3, 4, 5}}
Output: 11 32 29
Explanation:
After applying 1st Query 4 times,
Array will be: 5 6 3
After applying 2nd Query 3 times,
Array will be: 11 12 9
After applying 3rd Query 5 times,
Array will be: 11 32 29
Therefore, the final array will be {11, 32, 29}.
Input: arr[] = {1}, M = 1, Q[][] = {{1, 1, 1, 1}}
Output: 2
Explanation:
After applying 1st and the only query 1 time only.
Array will be: 2
Naive Approach: The simplest approach is to perform each query on the given array i.e., for each query {a, b, val, f} traverse the array over the range [a, b] and increase each element by value val to f number of times. Print the array after performing each query.
Time Complexity: O(N * M * max(Freq))
Auxiliary Space: O(1)
Better Approach: The idea is based on the difference array which can be used in Range Update operations. Below are the steps:
- Find the difference array D[] of a given array A[] is defined as D[i] = (A[i] – A[i – 1]) (0 < i < N) and D[0] = A[0] considering 0 based indexing.
- Add val to D[a – 1] and subtract it from D[(b – 1) + 1], i.e., D[a – 1] += val, D[(b – 1) + 1] -= val. Perform this operation Freq number of times.
- Now update the given array using the difference array. Update A[0] to D[0] and print it. For rest of the elements, do A[i] = A[i-1] + D[i].
- Print the resultant array after the above steps.
Time Complexity: O(N + M * max(Freq))
Auxiliary Space: O(N) Extra space for Difference Array
Efficient Approach: This approach is similar to the previous approach but an extended version of the application of a difference array. Previously the task was to update values from indices a to b by val, f number of times. Here instead of calling the range update function f number of times, call it only once for each query:
- Update values from indices a to b by val*f, only 1 time for each query.
- Add val*f to D[a – 1] and subtract it from D[(b – 1) + 1], i.e., increase D[a – 1] by val*f, and decrease D[b] by val*f.
- Now update the main array using the difference array. Update A[0] to D[0] and print it.
- For rest of the elements, Update A[i] by (A[i-1] + D[i]).
- Print the resultant array after the above steps.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
vector< int > initializeDiffArray(
vector< int >& A)
{
int N = A.size();
vector< int > D(N + 1);
D[0] = A[0], D[N] = 0;
for ( int i = 1; i < N; i++)
D[i] = A[i] - A[i - 1];
return D;
}
void update(vector< int >& D, int l,
int r, int x)
{
D[l] += x;
D[r + 1] -= x;
}
void UpdateDiffArray(vector< int >& DiffArray,
int Start, int End,
int Val, int Freq)
{
update(DiffArray, Start - 1,
End - 1, Val * Freq);
}
void queriesInput(vector< int >& DiffArray,
int Q[][4], int M)
{
for ( int i = 0; i < M; i++) {
UpdateDiffArray(DiffArray, Q[i][0],
Q[i][1], Q[i][2],
Q[i][3]);
}
}
void UpdateArray(vector< int >& A,
vector< int >& D)
{
for ( int i = 0; i < A.size(); i++) {
if (i == 0) {
A[i] = D[i];
}
else {
A[i] = D[i] + A[i - 1];
}
}
}
void PrintArray(vector< int >& A)
{
for ( int i = 0; i < A.size(); i++) {
cout << A[i] << " " ;
}
return ;
}
void printAfterUpdate(vector< int >& A,
int Q[][4], int M)
{
vector< int > DiffArray
= initializeDiffArray(A);
queriesInput(DiffArray, Q, M);
UpdateArray(A, DiffArray);
PrintArray(A);
}
int main()
{
int N = 3, M = 3;
vector< int > A{ 1, 2, 3 };
int Q[][4] = { { 1, 2, 1, 4 },
{ 1, 3, 2, 3 },
{ 2, 3, 4, 5 } };
printAfterUpdate(A, Q, M);
return 0;
}
|
Java
import java.util.*;
class GFG{
static int N = 3 , M = 3 ;
static int []A = new int [N];
static int []D = new int [N + 1 ];
static void initializeDiffArray()
{
D[ 0 ] = A[ 0 ];
D[N] = 0 ;
for ( int i = 1 ; i < N; i++)
D[i] = A[i] - A[i - 1 ];
}
static void update( int l,
int r, int x)
{
D[l] += x;
D[r + 1 ] -= x;
}
static void UpdateDiffArray( int Start, int End,
int Val, int Freq)
{
update(Start - 1 ,
End - 1 , Val * Freq);
}
static void queriesInput( int Q[][])
{
for ( int i = 0 ; i < M; i++)
{
UpdateDiffArray(Q[i][ 0 ], Q[i][ 1 ],
Q[i][ 2 ], Q[i][ 3 ]);
}
}
static void UpdateArray()
{
for ( int i = 0 ; i < N; i++)
{
if (i == 0 )
{
A[i] = D[i];
}
else
{
A[i] = D[i] + A[i - 1 ];
}
}
}
static void PrintArray()
{
for ( int i = 0 ; i < N; i++)
{
System.out.print(A[i] + i +
1 + " " );
}
return ;
}
static void printAfterUpdate( int []A,
int Q[][], int M)
{
initializeDiffArray();
queriesInput( Q);
UpdateArray();
PrintArray();
}
public static void main(String[] args)
{
int []A = { 1 , 2 , 3 };
int [][]Q = {{ 1 , 2 , 1 , 4 },
{ 1 , 3 , 2 , 3 },
{ 2 , 3 , 4 , 5 }};
printAfterUpdate(A, Q, M);
}
}
|
Python3
def initializeDiffArray(A):
N = len (A)
D = [ 0 ] * (N + 1 )
D[ 0 ] = A[ 0 ]
D[N] = 0
for i in range ( 1 , N):
D[i] = A[i] - A[i - 1 ]
return D
def update(D, l, r, x):
D[l] + = x
D[r + 1 ] - = x
def UpdateDiffArray(DiffArray, Start,
End, Val, Freq):
update(DiffArray, Start - 1 ,
End - 1 , Val * Freq)
def queriesInput(DiffArray, Q, M):
for i in range (M):
UpdateDiffArray(DiffArray, Q[i][ 0 ],
Q[i][ 1 ], Q[i][ 2 ],
Q[i][ 3 ])
def UpdateArray(A, D):
for i in range ( len (A)):
if (i = = 0 ):
A[i] = D[i]
else :
A[i] = D[i] + A[i - 1 ]
def PrintArray(A):
for i in range ( len (A)):
print (A[i], end = " " )
return
def printAfterUpdate(A, Q, M):
DiffArray = initializeDiffArray(A)
queriesInput(DiffArray, Q, M)
UpdateArray(A, DiffArray)
PrintArray(A)
if __name__ = = '__main__' :
N = 3
M = 3
A = [ 1 , 2 , 3 ]
Q = [ [ 1 , 2 , 1 , 4 ],
[ 1 , 3 , 2 , 3 ],
[ 2 , 3 , 4 , 5 ] ]
printAfterUpdate(A, Q, M)
|
C#
using System;
class GFG{
static int N = 3, M = 3;
static int [] A = new int [N];
static int [] D = new int [N + 1];
static void initializeDiffArray()
{
D[0] = A[0];
D[N] = 0;
for ( int i = 1; i < N; i++)
D[i] = A[i] - A[i - 1];
}
static void update( int l,
int r, int x)
{
D[l] += x;
D[r + 1] -= x;
}
static void UpdateDiffArray( int Start, int End,
int Val, int Freq)
{
update(Start - 1,
End - 1, Val * Freq);
}
static void queriesInput( int [, ] Q)
{
for ( int i = 0; i < M; i++)
{
UpdateDiffArray(Q[i, 0], Q[i, 1],
Q[i, 2], Q[i, 3]);
}
}
static void UpdateArray()
{
for ( int i = 0; i < N; i++)
{
if (i == 0)
{
A[i] = D[i];
}
else
{
A[i] = D[i] + A[i - 1];
}
}
}
static void PrintArray()
{
for ( int i = 0; i < N; i++)
{
Console.Write(A[i] + i +
1 + " " );
}
return ;
}
static void printAfterUpdate( int [] A,
int [, ] Q, int M)
{
initializeDiffArray();
queriesInput(Q);
UpdateArray();
PrintArray();
}
public static void Main(String[] args)
{
int [] A = {1, 2, 3};
int [, ] Q = {{1, 2, 1, 4},
{1, 3, 2, 3},
{2, 3, 4, 5}};
printAfterUpdate(A, Q, M);
}
|
Javascript
<script>
let N = 3, M = 3;
let A = new Array(N).fill(0);
let D = new Array(N+1).fill(0);
function initializeDiffArray()
{
D[0] = A[0];
D[N] = 0;
for (let i = 1; i < N; i++)
D[i] = A[i] - A[i - 1];
}
function update(l, r, x)
{
D[l] += x;
D[r + 1] -= x;
}
function UpdateDiffArray(Start, End, Val, Freq)
{
update(Start - 1,
End - 1, Val * Freq);
}
function queriesInput(Q)
{
for (let i = 0; i < M; i++)
{
UpdateDiffArray(Q[i][0], Q[i][1],
Q[i][2], Q[i][3]);
}
}
function UpdateArray()
{
for (let i = 0; i < N; i++)
{
if (i == 0)
{
A[i] = D[i];
}
else
{
A[i] = D[i] + A[i - 1];
}
}
}
function PrintArray()
{
for (let i = 0; i < N; i++)
{
document.write(A[i] + i +
1 + " " );
}
return ;
}
function printAfterUpdate(A, Q, M)
{
initializeDiffArray();
queriesInput( Q);
UpdateArray();
PrintArray();
}
let a = [1, 2, 3];
let Q = [[1, 2, 1, 4],
[1, 3, 2, 3],
[2, 3, 4, 5]];
printAfterUpdate(a, Q, M);
</script>
|
Time Complexity: O(N + M)
Auxiliary Space: O(N)