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