数论-快速幂
快速幂
- 模板代码
- 推导过程
求 A^B mod C,时间复杂度 O(logB)
模板代码
using ll = long long; // 可以在头文件中添加这行ll qmi(ll a, ll b, ll c)
{ll ans = 1; // 初始化结果为 1a %= c; // 将 a 取模 c,确保 a 小于 cwhile (b) // 当 b 不为零时循环{if (b & 1) // 如果 b 是奇数{ans = (ans * a) % c; // 更新结果}a = (a * a) % c; // 将 a 平方并取模 cb >>= 1; // 将 b 右移一位(相当于除以 2)}return ans; // 返回结果
}
推导过程
要计算 ( a × b ) m o d p (a \times b) \bmod p (a×b)modp ,我们已经知道 a = k 1 p + q 1 a=k_1 p+q_1 a=k1p+q1 和 b = k 2 p + q 2 b=k_2 p+q_2 b=k2p+q2 。接下来我们先回顾一下 a × b a \times b a×b 的表达式:
a × b = k 1 k 2 p 2 + ( k 1 q 2 + q 1 k 2 ) p + q 1 q 2 a \times b=k_1 k_2 p^2+\left(k_1 q_2+q_1 k_2\right) p+q_1 q_2 a×b=k1k2p2+(k1q2+q1k2)p+q1q2
现在我们需要对这个结果取模 p p p ,即计算 ( a × b ) m o d p (a \times b) \bmod p (a×b)modp 。
逐项取模:
- k 1 k 2 p 2 m o d p : k_1 k_2 p^2 \bmod p: k1k2p2modp:
- p 2 p^2 p2 是 p p p 的倍数,所以 k 1 k 2 p 2 m o d p = 0 k_1 k_2 p^2 \bmod p=0 k1k2p2modp=0 。
- ( k 1 q 2 + q 1 k 2 ) p m o d p \left(k_1 q_2+q_1 k_2\right) p \bmod p (k1q2+q1k2)pmodp :
- 这一项中有一个 p p p ,所以也是 p p p 的倍数,因此 ( k 1 q 2 + q 1 k 2 ) p m o d p = 0 \left(k_1 q_2+q_1 k_2\right) p \bmod p=0 (k1q2+q1k2)pmodp=0 。
- q 1 q 2 m o d p : q_1 q_2 \bmod p: q1q2modp:
- 这项中不含 p p p ,所以我们直接取模, q 1 q 2 m o d p q_1 q_2 \bmod p q1q2modp 就是结果。
结论:
( a × b ) m o d p = q 1 q 2 m o d p (a \times b) \bmod p=q_1 q_2 \bmod p (a×b)modp=q1q2modp
因此, ( a × b ) m o d p (a \times b) \bmod p (a×b)modp 等于 q 1 q 2 m o d p ∘ ↓ q_1 q_2 \bmod p_{\circ} \downarrow q1q2modp∘↓
例如计算310
计算步骤:
- 初始化:
- ans = 1 , a = 3 , b = 10 =1, a=3, b=10 =1,a=3,b=10 (二进制 101 0 2 1010_2 10102 ) 。
- 第一步 ( b = 1010 _ 2 ) : \left(b=1010 \_2\right): (b=1010_2):
- 最低位为 0 ,跳过乘法。
- 更新 a = 9 ( 3 2 ) a=9\left(3^2\right) a=9(32) 。
- 第二步 ( b = 101 _ 2 ) \left(b=101 \_2\right) (b=101_2) :
- 最低位为 1 ,乘以 ans = 9 × 3 = 27 =9 \times 3=27 =9×3=27 。
- 更新 a = 81 ( 9 2 ) a=81\left(9^2\right) a=81(92) 。
- 第三步 ( b = 10 _ 2 ) : \left(b=10 \_2\right): (b=10_2):
- 最低位为 0 ,跳过乘法。
- 更新 a = 6561 ( 8 1 2 ) a=6561\left(81^2\right) a=6561(812) 。
- 第四步 ( b = 1 _ 2 ) : \left(b=1 \_2\right): (b=1_2):
- 最低位为 1 ,乘以 ans = 27 × 6561 = 177147 =27 \times 6561=177147 =27×6561=177147 。
- 更新 a = 43046721 ( 656 1 2 ) a=43046721\left(6561^2\right) a=43046721(65612) 。
-
- 结果:
- 3 10 = 177147 3^{10}=177147 310=177147 。