快速幂取余 总结

即求:a^b mod c

算法1(时间复杂度:O(b)):

直接计算

int ans = 1,i;
for(i=0;ii++)
    ans *= a;
ans %= c;

问题在于当a,b过大时,容易溢出。

算法2(时间复杂度:O(b)):

首先明确2个公式:
(1):a^b mod c = [(a mod c)^b] mod c
(2): (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) mod c = (c的倍数 + de) mod c = de mod c
公式1 可由 公式2 推得。

int ans = 1,i;
a %= c;
for(i=0;ii++)
    ans *= a;
ans %= c;

这个改进不大,只是减小了数据溢出的可能。

算法3(时间复杂度:O(log b)):

首先公式:
这里写图片描述
每次用此公式迭代即为快速幂取余的算法!

最后快速幂取余代码:

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(n==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;    
}

我的原博客

你可能感兴趣的:(ACM,快速幂)