Source code for titan_pylib.data_structures.set.multiset_quadratic_division
1from typing import Iterable
2
3
[docs]
4class MultisetQuadraticDivision:
5
6 # OrderedMultiset[int]
7 # Space Complexity : O(u)
8 # add / discard / remove / contains : O(1)
9 # kth_elm : O(√u)
10
11 def __init__(self, u: int, a: Iterable[int] = []):
12 self.data = [0] * u
13 self.size = int(u**0.5) + 1
14 self.bucket_cnt = (u + self.size - 1) // self.size
15 self.bucket_data = [0] * self.bucket_cnt
16 self._len = 0
17 for e in a:
18 self.add(e)
19
[docs]
20 def add(self, key: int, cnt: int = 1) -> None:
21 self._len += cnt
22 self.data[key] += cnt
23 self.bucket_data[key // self.size] += cnt
24
[docs]
25 def discard(self, key: int, cnt: int = 1) -> None:
26 cnt = min(cnt, self.data[key])
27 self._len -= cnt
28 self.data[key] -= cnt
29 self.bucket_data[key // self.size] -= cnt
30
[docs]
31 def remove(self, key: int, cnt: int = 1) -> None:
32 self.data[key] -= cnt
33 self.bucket_data[key // self.size] -= cnt
34
[docs]
35 def count(self, key: int) -> int:
36 return self.data[key]
37
38 def __contains__(self, key: int):
39 return self.data[key] != 0
40
41 def __getitem__(self, k: int) -> int:
42 indx = 0
43 data, bucket_data = self.data, self.bucket_data
44 while bucket_data[indx] < k:
45 k -= bucket_data[indx]
46 indx += 1
47 indx *= self.size
48 while data[indx] == 0 or data[indx] <= k:
49 k -= data[indx]
50 indx += 1
51 return indx
52
53 def __len__(self):
54 return self._len