【模板】快速幂

1.快速幂

快速幂,顾名思义,就是快速地计算 a aab 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}31111 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)=383231

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(ab) % p=(a % pb % p) % p

  • ( a ∗ b )   %   p = ( a   %   p ∗ b   %   p )   %   p (a * b) \ \%\ p = (a\ \%\ p * b\ \%\ p)\ \%\ p(ab) % p=(a % pb % 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=(3643163831) % 7=(4423) % 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;
}

版权声明:本文为qq_42815188原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。