27
27
- a[1] + a[2] + a[3] + a[4] + a[5] = 3+3+1+7+2 = 16
28
28
- answer is 16
29
29
30
- Time Complexity:- O(N + Q)
31
- -- O(N) pre-calculation time to calculate the prefix sum array
32
- -- and O(1) time per each query = O(1 * Q) = O(Q) time
33
-
34
- Space Complexity:- O(N Log N + Q Log N)
30
+ Time Complexity:- O(N Log N + Q Log N)
35
31
-- O(N Log N) time for building the segment tree
36
32
-- O(log n) time for each query
37
33
-- Q queries are there so total time complexity is O(Q Log n)
38
34
35
+ Space Complexity:- O(N)
36
+
39
37
Algorithm:-
40
38
We first build the segment tree. An example of what the tree would look like:-
41
39
(query type is sum)
83
81
Query both the children and add their results and return that
84
82
"""
85
83
86
-
87
84
class SegmentTree :
88
85
def __init__ (self , arr , merge_func , default ):
89
86
"""
@@ -98,7 +95,7 @@ def __init__(self, arr, merge_func, default):
98
95
self .n = len (arr )
99
96
100
97
# while self.n is not a power of two
101
- while (self .n & (self .n - 1 )) != 0 :
98
+ while (self .n & (self .n - 1 )) != 0 :
102
99
self .n += 1
103
100
self .arr .append (default )
104
101
@@ -110,9 +107,8 @@ def __init__(self, arr, merge_func, default):
110
107
self .segment_tree [self .n + i ] = arr [i ]
111
108
112
109
for i in range (self .n - 1 , 0 , - 1 ):
113
- self .segment_tree [i ] = self .merge_func (
114
- self .segment_tree [2 * i ], self .segment_tree [2 * i + 1 ]
115
- )
110
+ self .segment_tree [i ] = self .merge_func (self .segment_tree [2 * i ],
111
+ self .segment_tree [2 * i + 1 ])
116
112
117
113
def update (self , index , value ):
118
114
"""
@@ -122,16 +118,15 @@ def update(self, index, value):
122
118
123
119
while index >= 1 :
124
120
index //= 2 # Go to the parent of index
125
- self .segment_tree [index ] = self .merge_func (
126
- self .segment_tree [2 * index ], self .segment_tree [2 * index + 1 ]
127
- )
121
+ self .segment_tree [index ] = self .merge_func (self .segment_tree [2 * index ],
122
+ self .segment_tree [2 * index + 1 ])
128
123
129
124
def query (self , left , right , node_index = 1 , node_left = 0 , node_right = None ):
130
125
"""
131
126
Finds the answer of self.merge_query(left, left+1, left+2, left+3, ..., right)
132
127
"""
133
128
if not node_right :
134
- # We cant add self.n as the default value in the function
129
+ # We can't add self.n as the default value in the function
135
130
# because self itself is a parameter so we do it this way
136
131
node_right = self .n
137
132
@@ -151,5 +146,5 @@ def query(self, left, right, node_index=1, node_left=0, node_right=None):
151
146
# of the query values of both the children nodes
152
147
return self .merge_func (
153
148
self .query (left , right , node_index * 2 , node_left , mid ),
154
- self .query (left , right , node_index * 2 + 1 , mid + 1 , node_right ),
149
+ self .query (left , right , node_index * 2 + 1 , mid + 1 , node_right )
155
150
)
0 commit comments