Source code for titan_pylib.algorithm.doubling

 1from typing import Callable
 2
 3
[docs] 4class Doubling: 5 """ダブリングテーブルを構築します。 6 :math:`O(n\\log{lim})` です。 7 8 Args: 9 n (int): テーブルサイズです。 10 すべての ``i`` に対して :math:`0 \leq ``move_to(i)`` < n` である必要があります。 11 lim (int): クエリの最大数です。 12 move_to (Callable[[int], int]): 遷移関数です。 ``u`` から ``v`` へ遷移します。 13 """ 14 15 def __init__(self, n: int, lim: int, move_to: Callable[[int], int]) -> None: 16 self.move_to = move_to 17 self.n = n 18 self.lim = lim 19 self.log = max(1, lim.bit_length()) 20 db = [[] for _ in range(self.log + 1)] 21 db[0] = [move_to(i) for i in range(self.n)] 22 for k in range(self.log): 23 db[k + 1] = [db[k][db[k][i]] for i in range(self.n)] 24 self.db = db 25
[docs] 26 def kth(self, start: int, k: int) -> int: 27 """``start`` から ``k`` 個進んだ状態を返します。 28 :math:`O(\\log{k})` です。 29 30 Args: 31 start (int): スタートの状態です。 32 k (int): 遷移関数を適用する回数です。 33 """ 34 db = self.db 35 now = start 36 for i in range(self.log): 37 if k & 1: 38 now = db[i][now] 39 k >>= 1 40 return now