快速幂快速乘

Posted -ackerman

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了快速幂快速乘相关的知识,希望对你有一定的参考价值。

在ACM的比赛中,我们经常会遇到指数型的数据的取模问题。

如果我们直接对数据进行取模,由于题目所给的数据的范围很大,会导致爆int 或者 long long

所以我们要采取快速幂取模

 

先看一组例子:

2*2*2*2*2*2*2*2*2*2*2

我们可以这样去算

原式=4*4*4*4*4*2

=8*8*4*2

=16*4*2

就是先合并后计算,这样就可以减少计算的步骤

 

快速幂的基本理论: 积的取余等于取余的积取余

快速幂就是我们先不断的降低a,b的规模,然后再进行计算

 

a^b

降低a的规模:  只要让 a变成a*a

降低b的规模:  如果b是偶数,那么每次a=a*a之后,b=b/2

          如果b是奇数,那么我们就先把这个多出来的数先跳出来,然后再用偶数的处理方法

 

从而我们就可以得到快速幂的代码了!

LL mul(LL a,LL b)

    LL sum = 1;
    a = a % mod;
    while (b>0)
    
        if (b%2==1) // b是奇数
        
            sum = (a*sum)%mod;
        
        a = (a*a) % mod;
        b = b/2;
    
    sum = sum%mod;
    return sum;

 

这里我们再讲一个快速乘,也可以说是大数乘法

快速乘法使用二进制将乘法转化为加法,既加快可以加快运算速度,又可以防止直接相乘之后溢出

LL mul(LL a,LL b)

    LL ans = 0;
    a = a % mod;
    while (b)
    
        if (b & 1) // b是奇数
        
            ans = (ans + a) % mod;
        
        a = (a + a) % mod;
        b >>= 1;
    
    return ans;

 

既然已经知道了快速乘  为什么不用快速乘去优化下我们的快速幂呢?

ll mul(ll a,ll b,ll mod)

    a%=mod;
    b%=mod;
    ll res=0;
    while(b)
        if(b&1)
            res+=a;
            if(res>=mod)
                res-=mod;
        
        b>>=1;
        a<<=1;
        if(a>=mod)
            a-=mod;
    
    return res;

ll quickPow(ll a,ll b,ll m)

    ll res=1;
    while(b)
        if(b&1)
            res=mul(res,a,m);
        a=mul(a,a,m);
        b>>=1;
    
    return res;

 

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

快速幂和快速乘

算法初步:快速乘,快速幂,矩阵快速幂

关于快速幂快速乘矩阵快速幂

快速幂 和 快速乘

快速幂和慢速乘

快速幂快速乘