Skip to content

Commit

Permalink
Added W09 materials
Browse files Browse the repository at this point in the history
  • Loading branch information
IvanSol committed Dec 2, 2024
1 parent 260fc80 commit 88b7141
Show file tree
Hide file tree
Showing 7 changed files with 170 additions and 1 deletion.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,8 @@
| 06 | KMP & Heap | [Slides][Slides_W06] | [Test][WarmUp_test_W06] | [Contest][ContestID_W06] | 18.11.2024 19:00 UTC+3 |
| 07 | DFS & BFS | [Slides][Slides_W07] | [Test][WarmUp_test_W07] | [Contest][ContestID_W07] | 25.11.2024 19:00 UTC+3 |
| 08 | Shortest paths | [Slides][Slides_W08] | [Test][WarmUp_test_W08] | [Contest][ContestID_W08] | 02.12.2024 19:00 UTC+3 |
| 09 | RSQ & RMQ | [Slides][Slides_W09] | [Test][WarmUp_test_W09] | [Contest][ContestID_W09] | 09.12.2024 19:00 UTC+3 |
<!---
| 09 | RSQ & RMQ | [Slides][Slides_W09] | [Test][WarmUp_test_W09] | [Contest][ContestID_W09] | ??.12.2024 19:00 UTC+3 |
| 10 | Hashing | [Slides][Slides_W10] | [Test][WarmUp_test_W10] | [Contest][ContestID_W10] | ??.12.2024 19:00 UTC+3 |
| 11 | Binary Search Tree | [Slides][Slides_W11] | None | None | None |
--->
Expand Down
Binary file added week09_rsq_rmq/MSAI.2024.Algo.W09.slides.pdf
Binary file not shown.
30 changes: 30 additions & 0 deletions week09_rsq_rmq/fenwick.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
class RSQFenwick:
def __init__(self, N):
self.N = N
self.f = [0] * self.N

def query(self, i):
res = 0
while i >= 0:
res += self.f[i]
i -= ~i & (i + 1)
return res

def update(self, i, delta):
while i < self.N:
self.f[i] += delta
i += ~i & (i + 1)

def rsq(self, left, right):
return self.query(right - 1) - self.query(left - 1)


if __name__ == '__main__':
N = int(input())
s = RSQFenwick(N)
while True:
a, b, c = input().split()
if a == '+':
s.update(int(b), int(c))
elif a == '?':
print(s.rsq(int(b), int(c)))
16 changes: 16 additions & 0 deletions week09_rsq_rmq/prefix_sum.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
class RSQPrefixSum:
def __init__(self, a):
self.s = [0]
for v in a:
self.s.append(self.s[-1] + v)

def rsq(self, l, r):
return self.s[r] - self.s[l]


if __name__ == '__main__':
a = list(map(int, input().split()))
s = RSQPrefixSum(a)
while True:
l, r = map(int, input().split())
print(s.rsq(l, r))
47 changes: 47 additions & 0 deletions week09_rsq_rmq/rsq_segmenttree.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
from math import log2, floor, ceil


class RSQSegmentTree:
neutral_value = 0

def __init__(self, a):
self.N = 2 ** int(ceil(log2(len(a))))
self.s = [None] * (self.N - 1) + list(a) + ([self.neutral_value] * (self.N - len(a)))
for i in range(self.N - 2, -1, -1):
self.refresh_s(i)

def refresh_s(self, i):
self.s[i] = self.s[2 * i + 1] + self.s[2 * i + 2]

def rsq_i(self, l, r, i, li, ri):
if (r <= li) or (ri <= l):
return self.neutral_value
if (l <= li) and (ri <= r):
return self.s[i]
middle = li + (ri - li) // 2
return (self.rsq_i(l, r, i * 2 + 1, li, middle) +
self.rsq_i(l, r, i * 2 + 2, middle, ri))

def update(self, i, v):
i += self.N - 1
self.s[i] = v
while i > 0:
i = (i - 1) // 2
self.refresh_s(i)

def rsq(self, l, r):
return self.rsq_i(l, r, 0, 0, self.N)


if __name__ == '__main__':
a = list(map(int, input().split()))
#N = int(input())
s = RSQSegmentTree(a)
while True:
a, b, c = input().split()
if a == '+':
s.update(int(b), int(c))
elif a == '?':
print(s.rsq(int(b), int(c)))
elif a == '!':
print(' '.join(map(str, s.a)))
37 changes: 37 additions & 0 deletions week09_rsq_rmq/sparcetable.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
from math import log2, floor, ceil

inf = 10**9


class RMQSparseTable:
def __init__(self, a):
N = len(a)
K = ceil(log2(N)) + 1

self.ST = [[None] * N for k in range(K)]
self.ST[0] = list(a)

for k in range(1, K):
for i in range(N):
if i + 2 ** (k - 1) < N:
self.ST[k][i] = min(self.ST[k - 1][i],
self.ST[k - 1][i + 2 ** (k - 1)])
else:
self.ST[k][i] = self.ST[k - 1][i]
for k in range(K):
print(' '.join(map(str, self.ST[k])))

def rmq(self, l, r):
if l == r:
return inf
k = floor(log2(r - l))
return min(self.ST[k][l],
self.ST[k][r - 2 ** k])


if __name__ == '__main__':
a = list(map(int, input().split()))
s = RMQSparseTable(a)
while True:
l, r = map(int, input().split())
print(s.rmq(l, r))
39 changes: 39 additions & 0 deletions week09_rsq_rmq/sqrt_decomposition.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
from math import sqrt, floor, ceil


class RSQSqrtDecomposition:
def __init__(self, a):
N = len(a)
self.k = max(int(ceil(sqrt(N))), 1)
self.a = a
self.b = [0] * (self.k + 1)

for i, v in enumerate(a):
self.b[i // self.k] += v

def rsq(self, l, r):
l_block = self.k * int(ceil(l / self.k))
r_block = self.k * int(floor(r / self.k))
if l_block > r_block:
return sum(self.a[l:r])
return (sum(self.a[l:l_block]) +
sum(self.b[l_block // self.k:r_block // self.k]) +
sum(self.a[r_block:r]))

def update(self, i, v):
delta = v - self.a[i]
self.a[i] = v
self.b[i // self.k] += delta


if __name__ == '__main__':
a = list(map(int, input().split()))
s = RSQSqrtDecomposition(a)
while True:
a, b, c = input().split()
if a == '+':
s.update(int(b), int(c))
elif a == '?':
print(s.rsq(int(b), int(c)))
elif a == '!':
print(' '.join(map(str, s.a)))

0 comments on commit 88b7141

Please sign in to comment.