-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathSegmentTree1.py
More file actions
65 lines (60 loc) · 1.89 KB
/
SegmentTree1.py
File metadata and controls
65 lines (60 loc) · 1.89 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
class SegmentTree():
def __init__(self, arr):
self.N = len(arr)
deep, lvl = 1, 1
while lvl < self.N:
deep += 1
lvl *= 2
self.deep = deep
self.values = [[None]]
lvl = 2*self.N
for x in range(self.deep):
s = []
sub, index = 1, 0
lvl = lvl//2+1 if lvl%2 else lvl//2
for y in range(lvl):
suma = 0
if x:
while index < len(self.values[x]) and index < 2*sub:
suma += self.values[x][index]
index += 1
else:
suma += arr[index]
index += 1
s.append(suma)
sub += 1
self.values.append(s)
return None
def update(self, index, nval):
pval = self.values[1][index]
change = nval-pval
for x in range(self.deep):
self.values[x+1][index] += change
index = index//2
return None
def sumRange(self, l, r, lvl=None):
if lvl == None:
r += 1
lvl = self.deep
if l==r or lvl == 0:
return 0
a = l//(2**(lvl-1))+1 if l%(2**(lvl-1)) else l//(2**(lvl-1))
b = r//(2**(lvl-1))
if a < b:
if a+1 == b:
suma = self.values[lvl][a]
elif a+2 == b:
suma = self.values[lvl][a] + self.values[lvl][a+1]
ll = a*(2**(lvl-1))
rr = b*(2**(lvl-1))
return self.sumRange(l,ll,lvl-1) + suma + self.sumRange(rr,r,lvl-1)
else:
return self.sumRange(l,r,lvl-1)
##################################################
# Example code
##################################################
nums = [1, 3, 5]
ST = SegmentTree(nums)
ST.sumRange(0, 2) # 1+3+5 = 9
ST.update(1, 2)
ST.sumRange(0, 2) # 2+3+5 = 8