Skip to content

Commit 75dce66

Browse files
+ Constant time range add operation on an array (modified) (for any array provided)
1 parent 114ffac commit 75dce66

File tree

1 file changed

+142
-0
lines changed

1 file changed

+142
-0
lines changed
Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
#http://www.geeksforgeeks.org/constant-time-range-add-operation-array/
2+
# modified to work with any array and sum to be added
3+
4+
def range_add_op(array: list, ranges: list, addition: int):
5+
6+
#work on the algorithm as we would for the array of 0s of len(array)
7+
arr_for_0 = [0 for i in range(len(array)+1)]
8+
9+
#work with the ranges (add at start and subtract at end+1)
10+
for start,end in ranges:
11+
arr_for_0[start] = arr_for_0[start] + addition
12+
arr_for_0[end+1] = arr_for_0[end+1] - addition
13+
14+
previous_ele = 0
15+
16+
#go through the list and calculate the sum that will come for each index
17+
for i,curr_ele in enumerate(arr_for_0[:len(array)]):
18+
previous_ele = previous_ele + curr_ele
19+
20+
#add the sum we got array of 0s to the original array
21+
array[i] += previous_ele
22+
23+
return array
24+
25+
#main
26+
if __name__=="__main__":
27+
array = list(map(int,input().split())) #List of int
28+
addition = int(input()) #Sum to be added if the element comes within the range
29+
no_of_additions = int(input()) #number of ranges that will be provided
30+
ranges = [] #ranges provided
31+
32+
#ranges given from index 0
33+
for i in range(no_of_additions):
34+
#get range from user
35+
ranges.append( list(map(int,input().split())) )
36+
37+
final_array = range_add_op(array, ranges, addition)
38+
39+
print("Final list after additions")
40+
print(' '.join(str(x) for x in final_array))
41+
42+
"""
43+
Input Explanation :
44+
- List of int
45+
- Sum to be added if the element comes within the range
46+
- Number of ranges that will be provided (no_of_additions)
47+
- Ranges provided [start end] (no_of_additions lines)
48+
49+
Input :
50+
10 20 10 0 10
51+
10
52+
3
53+
1 4
54+
2 3
55+
0 2
56+
57+
Output :
58+
Final list after additions
59+
20 40 40 20 20
60+
61+
"""
62+
63+
'''
64+
Given an array of size N which is initialized with all zeros. We are given many range add queries, which should be applied to this array. We need to print final updated array as our result.
65+
Examples:
66+
67+
N = 6
68+
Arr = [0, 0, 0, 0, 0, 0]
69+
rangeUpdate1 [0, 2], add 100
70+
Arr = [100, 100, 100, 0, 0, 0]
71+
rangeUpdate1 [1, 5], add 100
72+
Arr = [100, 200, 200, 100, 100, 100]
73+
rangeUpdate1 [2, 3], add 100
74+
Arr = [100, 200, 300, 200, 100, 100]
75+
Which is the final updated array.
76+
Recommended: Please try your approach on {IDE} first, before moving on to the solution.
77+
78+
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 array we will convert the above array into prefix sum array. See below example to understand,
79+
80+
Arr = [0, 0, 0, 0, 0, 0]
81+
rangeUpdate1 [0, 2], add 100
82+
Arr = [100, 0, 0, -100, 0, 0]
83+
rangeUpdate1 [1, 5], add 100
84+
Arr = [100, 100, 0, -100, 0, 0, -100]
85+
rangeUpdate1 [2, 3], add 100
86+
Arr = [100, 100, 100, -100, -100, 0, -100]
87+
Now we will convert above operation array to prefix sum array as shown below,
88+
Arr = [100, 200, 300, 200, 100, 100]
89+
Which is the final updated array.
90+
So in effect, when we add a value V to specific index of 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.
91+
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.
92+
C++Java
93+
// C++ program to get updated array after many array range
94+
// add operation
95+
#include <bits/stdc++.h>
96+
using namespace std;
97+
98+
// Utility method to add value val, to range [lo, hi]
99+
void add(int arr[], int N, int lo, int hi, int val)
100+
{
101+
arr[lo] += val;
102+
if (hi != N - 1)
103+
arr[hi + 1] -= val;
104+
}
105+
106+
// Utility method to get actual array from operation array
107+
void updateArray(int arr[], int N)
108+
{
109+
// convert array into prefix sum array
110+
for (int i = 1; i < N; i++)
111+
arr[i] += arr[i - 1];
112+
}
113+
114+
// method to print final updated array
115+
void printArr(int arr[], int N)
116+
{
117+
updateArray(arr, N);
118+
for (int i = 0; i < N; i++)
119+
cout << arr[i] << " ";
120+
cout << endl;
121+
}
122+
123+
// Driver code to test above methods
124+
int main()
125+
{
126+
int N = 6;
127+
128+
int arr[N] = {0};
129+
130+
// Range add Queries
131+
add(arr, N, 0, 2, 100);
132+
add(arr, N, 1, 5, 100);
133+
add(arr, N, 2, 3, 100);
134+
135+
printArr(arr, N);
136+
return 0;
137+
}
138+
Run on IDE
139+
140+
Output:
141+
100 200 300 200 100 100
142+
'''

0 commit comments

Comments
 (0)