快速幂学习笔记

快速幂

  1. 快速幂代码
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;
}
  1. 快速幂的数学原理?
    \(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不知道高到哪里去了。

posted @ 2020-11-26 20:22  面包络合物  阅读(84)  评论(0编辑  收藏  举报