快速幂取模和快速积取模 详解

快速幂取模:

是用来计算  ( a^b ) % c 的。

正常思路:

先计算 a^b ,然后将计算所得的结果 mod c, 但是这样有一个隐患,当a,b都很大时,a^b 就更大了,正常的数据类型肯定不可能存下,这就涉及到大数问题,很麻烦。不过我们有一种方式,可以避免出现大数。

快速幂取模:

我们运用公式:

当b为偶数时:a^b mod c = ((a^b/2)^2) mod c
当b为奇数时:a^b mod c = ((a^b/2)^2× a) mod c

通过公式发现,我们如果计算 a ^ b ,我们只需要计算  a ^ ( b/2 ) (一直递归下去)就好,然后mod c 之后,所得到的数字肯定不会大于c,就避免出现了大数的问题,这里我们只需要控制c的大小就可以。

代码:

非递归版本的:

#include<bits/stdc++.h>
typedef long long ll;
using namespace std;
ll a,b,c;
ll power(ll a,ll b,ll c)
{
    ll t=1;
    while (b)
    {
        if(b&1)
            t=t*a%c;
        a=a*a%c;
        b=b>>1;
    }
    return t;
}
int main()
{
    cin>>a>>b>>c;
    cout<<power(a,b,c);
}

快速积取模:

求(a*b*c*..........)% c1。

和快速幂取模一样,也是为了防止大数的出现。

代码:

非递归版本

#include<bits/stdc++.h>
typedef long long ll;
using namespace std;
ll mod;
ll modmul(ll ans,ll a)
{
    ll t=0;
    while (a)
    {
        if(a&1)
            t=(t+ans)%mod;
        ans=(ans+ans)%mod;
        a=a>>1;
    }
    return t;
}
int main()
{
    ll a;
    ll ans=1;
    cin>>mod;
    while (cin>>a)
    {
        if(!a)
            break ;
        ans=modmul(ans,a);
    }
    cout<<ans;
}

猜你喜欢

转载自blog.csdn.net/qq_40938077/article/details/81355443