Constant time range add operation on an array
Given an array of size N which is initialized with all zeros. We are given many ranges add queries, which should be applied to this array. We need to print the final updated array as our result.
Examples:
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.
This problem can be solved using segment tree with lazy updates in O(log N) time per query but we can do better here, as update operation is not given. We can process each query in constant time using this logic when a query to add V is given in range [a, b] we will add V to arr[a] and –V to arr[b+1] now if we want to get the actual values of the array we will convert the above array into prefix sum array.
See below example to understand:
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.
So in effect, when we add a value V to specific index of the array, It represents adding V to all elements right to this index, that is why we add –V after range to remove its effect after its range of add query.
Please note in below code, if range spans till the last index, the addition of –V is omitted to be in memory limit of the array.
Implementation:
C++
#include <bits/stdc++.h>
using namespace std;
void add( int arr[], int N, int lo, int hi, int val)
{
arr[lo] += val;
if (hi != N - 1)
arr[hi + 1] -= val;
}
void updateArray( int arr[], int N)
{
for ( int i = 1; i < N; i++)
arr[i] += arr[i - 1];
}
void printArr( int arr[], int N)
{
updateArray(arr, N);
for ( int i = 0; i < N; i++)
cout << arr[i] << " " ;
cout << endl;
}
int main()
{
int N = 6;
int arr[N] = {0};
add(arr, N, 0, 2, 100);
add(arr, N, 1, 5, 100);
add(arr, N, 2, 3, 100);
printArr(arr, N);
return 0;
}
|
Java
import java.io.*;
class GFG {
static void add( int arr[], int N, int lo, int hi,
int val)
{
arr[lo] += val;
if (hi != N - 1 )
arr[hi + 1 ] -= val;
}
static void updateArray( int arr[], int N)
{
for ( int i = 1 ; i < N; i++)
arr[i] += arr[i - 1 ];
}
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" );
}
public static void main(String[] args)
{
int N = 6 ;
int arr[] = new int [N];
add(arr, N, 0 , 2 , 100 );
add(arr, N, 1 , 5 , 100 );
add(arr, N, 2 , 3 , 100 );
printArr(arr, N);
}
}
|
Python3
def add(arr, N, lo, hi, val):
arr[lo] + = val
if (hi ! = N - 1 ):
arr[hi + 1 ] - = val
def updateArray(arr, N):
for i in range ( 1 , N):
arr[i] + = arr[i - 1 ]
def printArr(arr, N):
updateArray(arr, N)
for i in range (N):
print (arr[i], end = " " )
print ()
N = 6
arr = [ 0 for i in range (N)]
add(arr, N, 0 , 2 , 100 )
add(arr, N, 1 , 5 , 100 )
add(arr, N, 2 , 3 , 100 )
printArr(arr, N)
|
C#
using System;
class GFG {
static void add( int [] arr, int N, int lo, int hi,
int val)
{
arr[lo] += val;
if (hi != N - 1)
arr[hi + 1] -= val;
}
static void updateArray( int [] arr, int N)
{
for ( int i = 1; i < N; i++)
arr[i] += arr[i - 1];
}
static void printArr( int [] arr, int N)
{
updateArray(arr, N);
for ( int i = 0; i < N; i++)
Console.Write( "" + arr[i] + " " );
Console.Write( "\n" );
}
public static void Main()
{
int N = 6;
int [] arr = new int [N];
add(arr, N, 0, 2, 100);
add(arr, N, 1, 5, 100);
add(arr, N, 2, 3, 100);
printArr(arr, N);
}
}
|
PHP
<?php
function add(& $arr , $N , $lo , $hi , $val )
{
$arr [ $lo ] += $val ;
if ( $hi != $N - 1)
$arr [ $hi + 1] -= $val ;
}
function updateArray(& $arr , $N )
{
for ( $i = 1; $i < $N ; $i ++)
$arr [ $i ] += $arr [ $i - 1];
}
function printArr(& $arr , $N )
{
updateArray( $arr , $N );
for ( $i = 0; $i < $N ; $i ++)
echo $arr [ $i ] . " " ;
echo "\n" ;
}
$N = 6;
$arr = array_fill (0, $N , NULL);
add( $arr , $N , 0, 2, 100);
add( $arr , $N , 1, 5, 100);
add( $arr , $N , 2, 3, 100);
printArr( $arr , $N );
?>
|
Javascript
<script>
function add(arr,N,lo,hi,val)
{
arr[lo] += val;
if (hi != N - 1)
arr[hi + 1] -= val;
}
function updateArray(arr,N)
{
for (let i = 1; i < N; i++)
arr[i] += arr[i - 1];
}
function printArr(arr,N)
{
updateArray(arr, N);
for (let i = 0; i < N; i++)
document.write( "" + arr[i] + " " );
document.write( "<br>" );
}
let N = 6;
let arr= new Array(N);
for (let i=0;i<N;i++)
{
arr[i]=0;
}
add(arr, N, 0, 2, 100);
add(arr, N, 1, 5, 100);
add(arr, N, 2, 3, 100);
printArr(arr, N);
</script>
|
Output
100 200 300 200 100 100
Time Complexity: O(n)
Auxiliary Space: O(1)
Last Updated :
19 Sep, 2023
Like Article
Save Article
Share your thoughts in the comments
Please Login to comment...