快速幂算法基础

来源:互联网 发布:c语言 algin 编辑:程序博客网 时间:2024/06/08 05:31

快速幂算法主要应用于求幂模的问题。
我们可以先定义一个问题:
如何求2^31的最后一位数?显而易见,结果当然是8.这个问题是具有特殊性的,可以用某些特殊解法来处理。但是作为我们对快速幂的学习例程来看,我们需要从特殊问题中寻找一般算法。
对于这个问题,最脑残的算法是:

#include <iostream>#include <cstdio>#include <cmath>using namespace std;int main(){    int i,j,m=1,n,t;    cin>>t>>n;    while(--n>=0)m*=t;     cout<<m%10<<endl;    return 0;}

显见,这个算法对于大数据并不适用,可能造成内存溢出,因此我们做出:
while(--n>=0)m=(m*t)%10;
应用了离散数学中的一个定理:积的模等于模的积的模。
但是,时间复杂度并没有任何的改观。
为了解决时间复杂度问题,我们可以思考:对于n个a的积问题,是否可以转化为2*(n/2)个a的积的问题?答案是肯定的。再这样细分下去,不难想到,我们可以采用二分思想来解决这个问题。只是这里,我们并不把二分单独形成一个函数,我们仅仅采用while循环来解决二分算法的实现。(也称:二分幂)

#include <iostream>#include <cstdio>#include <cmath>using namespace std;int main(){    long long i,j,m=1,n,t,base;    cin>>t>>n;    t%=10;    while(n)    {        if(n%2==1)            m*=t;        t=(t*t)%10;        n/=2;    }    cout<<m%10<<endl;    return 0;}

经检验,这种算法可以在数据量为指数为10^16甚至更大时瞬间得出结果。
事实上,这也就是最基本的快速幂算法。
另则,在以上例程中我们使用的都是10作为基本模。可以单独导出一个变量Md来作为模数。这样可以实现任意模的快速幂。
对于更为复杂的问题,可能会用到快速幂与高精度的结合,以及快速幂的位运算实现方法,本文在此不作深入研究。

0 0
原创粉丝点击