Source code for titan_pylib.data_structures.cumulative_sum.cumulative_op

 1from typing import Generic, TypeVar, Callable, Iterable
 2
 3T = TypeVar("T")
 4
 5
[docs] 6class CumulativeOp(Generic[T]): 7 """抽象化累積和です。""" 8 9 def __init__( 10 self, a: Iterable[T], op: Callable[[T, T], T], inv: Callable[[T], T], e: T 11 ): 12 """ 13 :math:`O(n)` です。 14 15 Args: 16 a (Iterable[T]): ``CumulativeOp`` を構築する配列です。 17 op (Callable[[T, T], T]): 2項演算をする関数です。 18 inv (Callable[[T], T]): 逆元を返す関数です。 ``prod`` メソッドを使用する場合必要です。 19 e (T): 単位元です。 20 """ 21 a = list(a) 22 n = len(a) 23 acc = [e for _ in range(n + 1)] 24 for i in range(n): 25 acc[i + 1] = op(acc[i], a[i]) 26 self.n = n 27 self.acc = acc 28 self.a = a 29 self.op = op 30 self.inv = inv 31
[docs] 32 def pref(self, r: int) -> T: 33 """区間 ``[0, r)`` の演算結果を返します。 34 :math:`O(1)` です。 35 36 Args: 37 r (int): インデックスです。 38 """ 39 return self.acc[r]
40
[docs] 41 def prod(self, l: int, r: int) -> T: 42 """区間 `[l, r)` の演算結果を返します。 43 :math:`O(1)` です。 44 45 Args: 46 l (int): インデックスです。 47 r (int): インデックスです。 48 """ 49 assert ( 50 0 <= l <= r <= self.n 51 ), f"IndexError: {self.__class__.__name__}.prod({l}, {r})" 52 return self.op(self.acc[r], self.inv(self.acc[l]))
53
[docs] 54 def all_prod(self) -> T: 55 """区間 `[0, N)` の演算結果を返します。 56 :math:`O(1)` です。 57 """ 58 return self.acc[-1]
59 60 def __getitem__(self, k: int) -> T: 61 return self.a[k] 62 63 def __len__(self): 64 return len(self.a) 65 66 def __str__(self): 67 return str(self.acc) 68 69 __repr__ = __str__