累乗はモノイドに対して定義できる。
$a^{11} = a^{8 + 2 + 1}= a^8 a^4 a^1$ と考えて計算をする(指数の部分の2進展開をする)
$a$ の 2べき乗の部分は
と計算していく。
モノイドに一般化できる
$a^k$ の計算量は $O(\log k)$
$f: [N] \to [N]$ に対して前処理をすると、$k \leq K$ に対して $f^k (x)$ が高速に計算できる。ただし、$f^k$ は $f$ の $k$ 回合成とする。
競プロでの使い方
愚直との比較
ダブリングのクエリはキャッシュがうまく使えず定数倍が遅い
前処理のコードについて(ダブリングテーブルの作成)
dp[i][v] = dp[i - 1][dp[i - 1][v]]
// ↓こう書くほうが見通しが良い (合成をしていることがわかりやすい)
let f = &dp[i - 1];
dp[i][v] = f[f[v]]
メモ
ある種の漸化式が出てくると、累乗の話になりがち。(参考: 漸化式)