1.快速幂
快速幂,顾名思义,就是快速地计算 a aa 的 b bb 次幂。
时间复杂度为 O ( log n ) O(\log n)O(logn),与朴素的 O ( n ) O(n)O(n) 相比,效率有了极大的提高。
对于 a b a^bab 来说,b bb 是可以拆成二进制的。
例如求 3 11 3^{11}311,11 1111 的二进制是 1011 10111011,即 11 = 2 3 + 2 1 + 2 0 11 = 2^3 + 2^1 + 2^011=23+21+20,
那么 3 11 = 3 ( 2 3 + 2 1 + 2 0 ) = 3 ( 2 3 ) ∗ 3 ( 2 1 ) ∗ 3 ( 2 0 ) = 3 8 ∗ 3 2 ∗ 3 1 3^{11} = 3^{(2^3+2^1+2^0)} = 3^{(2^3)} * 3^{(2^1)} * 3^{(2^0)} = 3^8 * 3^2 * 3^1311=3(23+21+20)=3(23)∗3(21)∗3(20)=38∗32∗31
int quickPow(int a, int b)
{
int res = 1;
while (b)
{
if (b & 1) res *= a;
a *= a;
b >>= 1;
}
return res;
}
2.快速幂取模
快速幂取模,顾名思义,就是快速地计算 a b % m a^b\ \% \ mab % m 的值。
用到的公式:
( a + b ) % p = ( a % p + b % p ) % p (a + b) \ \%\ p = (a\ \%\ p + b\ \%\ p)\ \%\ p(a+b) % p=(a % p+b % p) % p
( a − b ) % p = ( a % p − b % p ) % p (a - b)\ \%\ p = (a\ \%\ p - b\ \%\ p)\ \%\ p(a−b) % p=(a % p−b % p) % p
( a ∗ b ) % p = ( a % p ∗ b % p ) % p (a * b) \ \%\ p = (a\ \%\ p * b\ \%\ p)\ \%\ p(a∗b) % p=(a % p∗b % p) % p
( a b ) % p = ( ( a % p ) b ) % p (a^b) \ \%\ p = ((a \ \%\ p)^b) \ \%\ p(ab) % p=((a % p)b) % p
以 3 89 % 7 3^{89} \ \%\ 7389 % 7 为例:
3 % 7 = 3 3\ \%\ 7 = 33 % 7=3
3 2 % 7 = 2 3^2\ \%\ 7 = 232 % 7=2
3 4 % 7 = ( 3 2 ) 2 % 7 = ( 3 2 % 7 ) 2 % 7 = 2 2 % 7 = 4 3^4\ \%\ 7 = (3^2)^2\ \%\ 7 = (3^2\ \%\ 7)^{2} \ \%\ 7 = 2^2 \ \%\ 7 = 434 % 7=(32)2 % 7=(32 % 7)2 % 7=22 % 7=4
3 8 % 7 = ( 3 4 ) 2 % 7 = ( 3 4 % 7 ) 2 % 7 = 4 2 % 7 = 2 3^8 \ \%\ 7 = (3^4)^2 \ \%\ 7 = (3^4 \ \%\ 7)^{2} \ \%\ 7 = 4^2 \ \%\ 7 = 238 % 7=(34)2 % 7=(34 % 7)2 % 7=42 % 7=2
3 16 % 7 = ( 3 8 ) 2 % 7 = ( 3 8 % 7 ) 2 % 7 = 2 2 % 7 = 4 3^{16} \ \%\ 7 = (3^8)^2 \ \%\ 7 = (3^8\ \%\ 7)^{2} \ \%\ 7 = 2^2 \ \%\ 7 = 4316 % 7=(38)2 % 7=(38 % 7)2 % 7=22 % 7=4
3 32 % 7 = ( 3 16 ) 2 % 7 = ( 3 16 % 7 ) 2 % 7 = 4 2 % 7 = 2 3^{32}\ \%\ 7 = (3^{16})^2 \ \%\ 7 = (3^{16}\ \%\ 7)^{2} \ \%\ 7 = 4^2 \ \%\ 7 = 2332 % 7=(316)2 % 7=(316 % 7)2 % 7=42 % 7=2
3 64 % 7 = ( 3 32 ) 2 % 7 = ( 3 32 % 7 ) 2 % 7 = 2 2 % 7 = 4 3^{64}\ \%\ 7 = (3^{32})^2\ \%\ 7 = (3^{32}\ \%\ 7)^{2} \ \%\ 7 = 2^2 \ \%\ 7 = 4364 % 7=(332)2 % 7=(332 % 7)2 % 7=22 % 7=4
3 89 % 7 = 3 ( 1011001 ) % 7 = ( 3 64 ∗ 3 16 ∗ 3 8 ∗ 3 1 ) % 7 = ( 4 ∗ 4 ∗ 2 ∗ 3 ) % 7 = 96 % 7 = 5 3^{89} \ \%\ 7 = 3^{(1011001)} \ \%\ 7 = (3^{64} * 3^{16} * 3^{8} * 3^{1}) \ \%\ 7 =(4 * 4 * 2 * 3) \ \%\ 7 = 96 \ \%\ 7 = 5389 % 7=3(1011001) % 7=(364∗316∗38∗31) % 7=(4∗4∗2∗3) % 7=96 % 7=5
int quickPow(int a, int b, int m)
{
int res = 1;
while (b)
{
if (b & 1) res = res * a % m;
a = a * a % m;
b >>= 1;
}
return res;
}