Source code for titan_pylib.data_structures.sparse_table.sparse_table

 1from typing import Generic, TypeVar, Iterable, Callable
 2
 3T = TypeVar("T")
 4
 5
[docs] 6class SparseTable(Generic[T]): 7 """``SparseTable`` です。 8 9 静的であることに注意してください。 10 """ 11 12 def __init__(self, a: Iterable[T], op: Callable[[T, T], T], e: T = None): 13 """ 14 :math:`O(n\\log{n})` です。 15 16 Args: 17 a (Iterable[T]): ``SparseTable`` を構築する配列です。 18 op (Callable[[T, T], T]): 2項演算の関数です。 19 e (T, optional): 単位元です。 20 """ 21 if not isinstance(a, list): 22 a = list(a) 23 self.size = len(a) 24 log = self.size.bit_length() - 1 25 data = [a] + [[]] * log 26 for i in range(log): 27 pre = data[i] 28 l = 1 << i 29 data[i + 1] = [op(pre[j], pre[j + l]) for j in range(len(pre) - l)] 30 self.data = data 31 self.op = op 32 self.e = e 33
[docs] 34 def prod(self, l: int, r: int) -> T: 35 """区間 ``[l, r)`` の総積を返します。 36 37 :math:`O(\\log{n})` です。 38 39 Args: 40 l (int): インデックスです。 41 r (int): インデックスです。 42 """ 43 assert ( 44 0 <= l <= r <= self.size 45 ), f"IndexError: {self.__class__.__name__}.prod({l}, {r}), len={self.size}" 46 if l == r: 47 return self.e 48 u = (r - l).bit_length() - 1 49 return self.op(self.data[u][l], self.data[u][r - (1 << u)])
50 51 def __getitem__(self, k: int) -> T: 52 assert ( 53 0 <= k < self.size 54 ), f"IndexError: {self.__class__.__name__}[{k}], len={self.size}" 55 return self.data[0][k] 56 57 def __len__(self): 58 return self.size 59 60 def __str__(self): 61 return str(self.data[0]) 62 63 def __repr__(self): 64 return f"{self.__class__.__name__}({self}, {self.op}, {self.e})"