快速幂 + 64位龟速乘法
快速幂
快速地求出 $ a^{b}\;mod\;p $, 其中 $ 1 \leq a,\,b,\,p \leq 10^{9} $
每一个正整数都有其唯一的二进制表示, 显然每一个正整数也都可以唯一地表示为若干指数不重复的2的次幂的和
即, 设 $b$ 在二进制表示下有 $k$ 位, 其中第 $i\,(0 \leq i < k)$ 位的数字是 $ c_{i} $, 则:
$ b=c_{k-1}2^{k-1}+c_{k-2}2^{k-2}+...+c_{0}2^{0} $
$ \Rightarrow $
$ a^{b} = a^{c_{k-1}\;2^{k-1}\;+\;c_{k-2}\;2^{k-2}\;+\;...\;+\;c_{0}\,2^{0}} $
又因为 $ a^{2^{i}} = (a^{2^{i-1}}\,)^{2} $, 我们可以通过 $k$ 次递推求出每一个乘积项, 当 $c_{i}=1$ 时, 将该乘积项累积到答案中
$b$ & 1可以取出b的最低位, 而 $b>>1$可以舍去 $b$ 的最低位, 二者结合可以遍历 $b$ 在二进制表示下的所有数位
由于 $b$ 的二进制表示的位数 $k$ 与$log\,b$ 同级, 所以整个算法的时间复杂度为 $O(log\,n)$
LL qmi(LL a, LL b, LL p) { LL ans = 1 % p; while(b) { if(b & 1) ans = ans * a % p; a = a * a % p; b >>= 1; } return ans; }
64位龟速乘法
求出 $ a \cdot b\;mod\;p $, 其中 $ 1 \leq a,\,b,\,p \leq 10^{18} $
同快速幂, 设 $b$ 在二进制表示下有 $k$ 位, 其中第 $i\,(0 \leq i < k)$ 位的数字是 $ c_{i} $, 则:
$ b=c_{k-1}2^{k-1}+c_{k-2}2^{k-2}+...+c_{0}2^{0} $
$ \Rightarrow $
$ a \cdot b = a\cdot(c_{k-1}\;2^{k-1}+c_{k-2}\;2^{k-2}+...+c_{0}2^{0}) $
展开得 $ = a\cdot c_{k-1}\;2^{k-1}+ ... + a\cdot c_{0}2^{0} $
求法与快速幂几乎一样, 只是将 × 改为 +, 时间复杂度也相同, 为 $O(log n)$, 因此得名龟速乘
LL qmul(LL a, LL b, LL p) { LL ans = 0; while(b) { if(b & 1) ans = (ans + a) % p; a = (a + a) % p; b >>= 1; } return ans; }

浙公网安备 33010602011771号