快速幂
- 快速幂代码
int Fastmi(int a,int b,int p)
{
int ans = 1 % p;
for(; b; b >>= 1)
{
if(b & 1) ans = (long long)ans * a % p;
a = (long long)a * a % p;
}
return ans;
}
- 快速幂的数学原理?
若(b)在二进制下有(k)位,第(i)位的数字是(c_i),则每一个正整数都可以唯一表示为若干个指数不重复的(2)的次幂的形式:
[b = c_{k-1}2^{k-1} + c_{k-2}2^{k-2} + cdots + c_{0}2^{0}
]
(a^b)可以如此表示:
[a^b = a^{c_{k-1}2^{k-1}} * a^{c_{k-2}2^{k-2}} * cdots * a^{c_{0}2^{0}}
]
每次循环我们都将(a)平方,这样(2)的次幂将被表示出来,即从(2^0)一直到(2^{k-1})。我们将b在二进制下的每一位取出,若是1,则说明这一项(c_i)不为(0),将乘积累乘到ans当中去;若是0,则(c_i)为(0),则ans的值不变。(b)&(1)运算可以取出(b)在二进制下的最低位(这也是为什么我们要从(2^0)一直累乘到(2^{k-1})的原因),而(b>>1)运算可以遍历(b)在二进制下的所有数位。
3. 快速幂的时间复杂度?
整个算法的时间复杂度为(O(log_2b)),比起只有(O(n))的pow不知道高到哪里去了。