Skip to content

Commit f07c8d5

Browse files
authored
Merge pull request #178 from SaBuZa/Lazy-Segment-Tree
Lazy Segment Tree
2 parents f6696d0 + 2617de8 commit f07c8d5

File tree

1 file changed

+90
-0
lines changed

1 file changed

+90
-0
lines changed

Diff for: data_structures/Binary Tree/LazySegmentTree.py

+90
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
import math
2+
3+
class SegmentTree:
4+
5+
def __init__(self, N):
6+
self.N = N
7+
self.st = [0 for i in range(0,4*N)] # approximate the overall size of segment tree with array N
8+
self.lazy = [0 for i in range(0,4*N)] # create array to store lazy update
9+
self.flag = [0 for i in range(0,4*N)] # flag for lazy update
10+
11+
def left(self, idx):
12+
return idx*2
13+
14+
def right(self, idx):
15+
return idx*2 + 1
16+
17+
def build(self, idx, l, r, A):
18+
if l==r:
19+
self.st[idx] = A[l-1]
20+
else :
21+
mid = (l+r)//2
22+
self.build(self.left(idx),l,mid, A)
23+
self.build(self.right(idx),mid+1,r, A)
24+
self.st[idx] = max(self.st[self.left(idx)] , self.st[self.right(idx)])
25+
26+
# update with O(lg N) (Normal segment tree without lazy update will take O(Nlg N) for each update)
27+
def update(self, idx, l, r, a, b, val): # update(1, 1, N, a, b, v) for update val v to [a,b]
28+
if self.flag[idx] == True:
29+
self.st[idx] = self.lazy[idx]
30+
self.flag[idx] = False
31+
if l!=r:
32+
self.lazy[self.left(idx)] = self.lazy[idx]
33+
self.lazy[self.right(idx)] = self.lazy[idx]
34+
self.flag[self.left(idx)] = True
35+
self.flag[self.right(idx)] = True
36+
37+
if r < a or l > b:
38+
return True
39+
if l >= a and r <= b :
40+
self.st[idx] = val
41+
if l!=r:
42+
self.lazy[self.left(idx)] = val
43+
self.lazy[self.right(idx)] = val
44+
self.flag[self.left(idx)] = True
45+
self.flag[self.right(idx)] = True
46+
return True
47+
mid = (l+r)//2
48+
self.update(self.left(idx),l,mid,a,b,val)
49+
self.update(self.right(idx),mid+1,r,a,b,val)
50+
self.st[idx] = max(self.st[self.left(idx)] , self.st[self.right(idx)])
51+
return True
52+
53+
# query with O(lg N)
54+
def query(self, idx, l, r, a, b): #query(1, 1, N, a, b) for query max of [a,b]
55+
if self.flag[idx] == True:
56+
self.st[idx] = self.lazy[idx]
57+
self.flag[idx] = False
58+
if l != r:
59+
self.lazy[self.left(idx)] = self.lazy[idx]
60+
self.lazy[self.right(idx)] = self.lazy[idx]
61+
self.flag[self.left(idx)] = True
62+
self.flag[self.right(idx)] = True
63+
if r < a or l > b:
64+
return -math.inf
65+
if l >= a and r <= b:
66+
return self.st[idx]
67+
mid = (l+r)//2
68+
q1 = self.query(self.left(idx),l,mid,a,b)
69+
q2 = self.query(self.right(idx),mid+1,r,a,b)
70+
return max(q1,q2)
71+
72+
def showData(self):
73+
showList = []
74+
for i in range(1,N+1):
75+
showList += [self.query(1, 1, self.N, i, i)]
76+
print (showList)
77+
78+
79+
if __name__ == '__main__':
80+
A = [1,2,-4,7,3,-5,6,11,-20,9,14,15,5,2,-8]
81+
N = 15
82+
segt = SegmentTree(N)
83+
segt.build(1,1,N,A)
84+
print (segt.query(1,1,N,4,6))
85+
print (segt.query(1,1,N,7,11))
86+
print (segt.query(1,1,N,7,12))
87+
segt.update(1,1,N,1,3,111)
88+
print (segt.query(1,1,N,1,15))
89+
segt.update(1,1,N,7,8,235)
90+
segt.showData()

0 commit comments

Comments
 (0)