Source code for titan_pylib.data_structures.fenwick_tree.dynamic_fenwick_tree
1from typing import Optional, Final
2
3
[docs]
4class DynamicFenwickTree:
5 """必要なところだけノードを作ります。"""
6
7 def __init__(self, u: int):
8 """Build DynamicFenwickTree [0, u)."""
9 assert isinstance(
10 u, int
11 ), f"TypeError: DynamicFenwickTree({u}), {u} must be int"
12 self._u: Final[int] = u
13 self._tree: dict[int, int] = {}
14 self._s: Final[int] = 1 << (u - 1).bit_length()
15
[docs]
16 def add(self, k: int, x: int) -> None:
17 assert (
18 0 <= k < self._u
19 ), f"IndexError: DynamicFenwickTree.add({k}, {x}), u={self._u}"
20 k += 1
21 while k <= self._u:
22 if k in self._tree:
23 self._tree[k] += x
24 else:
25 self._tree[k] = x
26 k += k & -k
27
[docs]
28 def pref(self, r: int) -> int:
29 assert (
30 0 <= r <= self._u
31 ), f"IndexError: DynamicFenwickTree.pref({r}), u={self._u}"
32 ret = 0
33 while r > 0:
34 ret += self._tree.get(r, 0)
35 r -= r & -r
36 return ret
37
[docs]
38 def sum(self, l: int, r: int) -> int:
39 assert (
40 0 <= l <= r <= self._u
41 ), f"IndexError: DynamicFenwickTree.sum({l}, {r}), u={self._u}"
42 # return self.pref(r) - self.pref(l)
43 _tree = self._tree
44 res = 0
45 while r > l:
46 res += _tree.get(r, 0)
47 r -= r & -r
48 while l > r:
49 res -= _tree.get(l, 0)
50 l -= l & -l
51 return res
52
[docs]
53 def bisect_left(self, w: int) -> Optional[int]:
54 i, s = 0, self._s
55 while s:
56 if i + s <= self._u:
57 if i + s in self._tree and self._tree[i + s] < w:
58 w -= self._tree[i + s]
59 i += s
60 elif i + s not in self._tree and 0 < w:
61 i += s
62 s >>= 1
63 return i if w else None
64
[docs]
65 def bisect_right(self, w: int) -> int:
66 i, s = 0, self._s
67 while s:
68 if i + s <= self._u:
69 if i + s in self._tree and self._tree[i + s] <= w:
70 w -= self._tree[i + s]
71 i += s
72 elif i + s not in self._tree and 0 <= w:
73 i += s
74 s >>= 1
75 return i
76
77 def __str__(self):
78 return str(self._tree)