快速幂总结
Posted 天外天
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了快速幂总结相关的知识,希望对你有一定的参考价值。
快速幂问题
即求:\\(a^b \\mod c\\)
暴力
直接暴力
时间复杂度:\\(O(b)\\)
int ans = 1,i;
for(i=0;i<b;i++)
ans *= a;
ans %= c;
问题在于当a,b过大时,容易溢出。
优化溢出
时间复杂度:\\(O(b)\\)
首先明确2个公式:
- \\(a^b \\mod c = [(a \\mod c)^b] \\mod c\\)
- \\((a*b) \\mod c = [(a \\mod c)*(b \\mod c)] \\mod c\\)
即:积的取余等于取余的积的取余!
证明:
设:\\(d = a \\mod c, e = b \\mod c\\)
则:\\(a = t*c+d, b = k*c+e\\)
可以推出:
\\[a*b \\equiv x*c+d*e \\equiv d*e \\pmod c
\\]
公式1可由公式2推得。
int ans = 1,i;
a %= c;
for(i=0;i<b;i++)
ans *= a;
ans %= c;
这个改进不大,只是减小了数据溢出的可能。
快速幂
时间复杂度:\\(O(\\log_2{b})\\)
公式:
\\[a^b \\mod c = (a^2)^ \\left( b/2 \\right) \\mod c, 当b为偶
\\]
\\[a^b \\mod c = ((a^2)^ \\left( b/2 \\right) * a) \\mod c, 当b为奇
\\]
依据上述两个公式,令\\(k = a^2 \\mod c\\),我们可以得出如下结论:
- 当b是偶数,即求\\(k^{b/2} \\mod c\\)
- 当b是奇数,即求\\(((k^{b/2} \\mod c) * a) \\mod c\\)
每次用此公式迭代即为快速幂取余算法!
int ans = 1;
a %= c;
while(b>0)
{
if(b%2==1) ans = (ans *a)%c;
b /= 2;
a = (a*a)%c;
}
看了算法竞赛(刘汝佳)之后发现还有一种写法,思想相同,用递归实现,代码:
int pow_mod(int a,int b,int c)
{
if(b==0) return 1;
int x = pow_mod(a,b/2,c);
long long ans = (long long)x * x % c;
if(b%2==1) ans = ans * a % c;
return (int)ans;
}
以上是关于快速幂总结的主要内容,如果未能解决你的问题,请参考以下文章