Source code for titan_pylib.data_structures.array.partial_persistent_array

 1from typing import Iterable, TypeVar, Generic
 2
 3T = TypeVar("T")
 4
 5
[docs] 6class PartialPersistentArray(Generic[T]): 7 """部分永続配列です。 8 最新版の更新と、過去へのアクセスが可能です。 9 """ 10 11 def __init__(self, a: Iterable[T]): 12 """``a`` から部分永続配列を構築します。 13 初期配列のバージョンは ``0`` です。 14 :math:`O(n)` です。 15 """ 16 self.a: list[list[T]] = [[e] for e in a] 17 self.t: list[list[int]] = [[0] for _ in range(len(self.a))] 18 self.last_time: int = 0 19
[docs] 20 def set(self, k: int, v: T, t: int) -> None: 21 """位置 ``k`` を ``v`` に更新します。 22 :math:`O(1)` です。 23 24 Args: 25 k (int): インデックスです。 26 v (T): 更新する値です。 27 t (int): 新たな配列のバージョンです。 28 """ 29 assert t >= self.last_time 30 assert t > self.t[k][-1] 31 self.a[k].append(v) 32 self.t[k].append(t) 33 self.last_time = t
34
[docs] 35 def get(self, k: int, t: int = -1) -> T: 36 """位置 ``k`` 、バージョン ``t`` の要素を返します。 37 :math:`O(\\log{n})` です。 38 39 Args: 40 k (int): インデックスです。 41 t (int, optional): バージョンです。デフォルトは最新バージョンです。 42 """ 43 if t == -1 or t >= self.t[k][-1]: 44 return self.a[k][-1] 45 tk = self.t[k] 46 ok, ng = 0, len(tk) 47 while ng - ok > 1: 48 mid = (ok + ng) // 2 49 if tk[mid] <= t: 50 ok = mid 51 else: 52 ng = mid 53 return self.a[k][ok]
54
[docs] 55 def tolist(self, t: int) -> list[T]: 56 """バージョン ``t`` の配列を返します。 57 :math:`O(n\\log{n})` です。 58 """ 59 return [self.get(i, t) for i in range(len(self))]
60
[docs] 61 def show(self, t: int) -> None: 62 print(f"Time: {t}", end="") 63 print([self.get(i, t) for i in range(len(self))])
64
[docs] 65 def show_all(self) -> None: 66 """すべてのバージョンの配列を表示します。""" 67 for i in range(self.last_time): 68 self.show(i)
69 70 def __len__(self): 71 return len(self.a)