Source code for titan_pylib.data_structures.set.mex_multiset

 1from titan_pylib.data_structures.segment_tree.segment_tree import SegmentTree
 2from typing import Iterable
 3
 4
[docs] 5class MexMultiset: 6 """``MexMultiset`` です。 7 8 各操作は `log` がつきますが、ANDセグ木の ``log`` で割と軽いです。 9 """ 10 11 def __init__(self, u: int, a: Iterable[int] = []) -> None: 12 """``[0, u)`` の範囲の mex を計算する ``MexMultiset`` を構築します。 13 14 時間・空間共に :math:`O(u)` です。 15 16 Args: 17 u (int): 値の上限です。 18 """ 19 data = [0] * (u + 1) 20 init_data = [1] * (u + 1) 21 for e in a: 22 if e <= u: 23 data[e] += 1 24 init_data[e] = 0 25 self.u: int = u 26 self.data: list[int] = data 27 self.seg: SegmentTree[int] = SegmentTree(init_data, op=lambda s, t: s | t, e=0) 28
[docs] 29 def add(self, key: int) -> None: 30 """``key`` を追加します。 31 32 :math:`O(\\log{n})` です。 33 """ 34 if key > self.u: 35 return 36 if self.data[key] == 0: 37 self.seg[key] = 0 38 self.data[key] += 1
39
[docs] 40 def remove(self, key: int) -> None: 41 """``key`` を削除します。 ``key`` は存在していなければなりません。 42 43 :math:`O(\\log{n})` です。 44 """ 45 if key > self.u: 46 return 47 if self.data[key] == 1: 48 self.seg[key] = 1 49 self.data[key] -= 1
50
[docs] 51 def mex(self) -> int: 52 """mex を返します。 53 54 :math:`O(\\log{n})` です。 55 """ 56 return self.seg.max_right(0, lambda lr: lr == 0)