快速幂总结

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个公式:

  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 \\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\\),我们可以得出如下结论:

  1. 当b是偶数,即求\\(k^{b/2} \\mod c\\)
  2. 当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;
}

以上是关于快速幂总结的主要内容,如果未能解决你的问题,请参考以下文章

疯子的算法总结 矩阵乘法 (矩阵快速幂)

矩阵快速幂总结

总结——数论:快速幂

快速幂总结

知识总结多项式全家桶(快速幂和开根)

机试练习总结05:快速幂O(logn)