nefu120-梅森素数(Lucas-Lehmer判定法和Miller测试法)


准备知识:

梅森素数:它是发现已知最大素数的有效途径。如果m是一个正整数,且是一个素数,则2^m-1必是素数。反之,如果m是一个正整数、素数,且2^m-1称作第m梅森数;如果p是一个素数,并且也是素数,那么就称为梅森素数。而梅森数可能是素数,也可能是合数。

(由于很多word公式无法导入,只能以截图方式展现。)

nefu120-梅森素数(Lucas-Lehmer判定法和Miller测试法)_第1张图片

Lucas-Lehmer判定法

#include 

using namespace std;

#define ll long long

ll multi(ll a,ll b,ll mod)
{
    ll ans=0;
    while(b>0)
    {
        if(b&1)
        {
            ans=(ans+a)%mod;
        }
        b>>=1;
        a=(a<<1)%mod;
    }
    return ans;
}



int main()
{
    int T;
    cin>>T;
    while(T--)
    {
        int p;
        ll r1 = 4,r2=0,mp=1;
        cin>>p;
        mp = (mp<

Miller测试法

这里用快速幂时,我们需要注意的是,如果直接a*a%n是有可能有溢出风险的,因为都是long long 类型的。所以这里还需要加入一个基于加法的快速乘法取模法,来求a*a%n。

#include 
#include 
#include 
#include 

#define ll long long
#define Times 12

using namespace std;

ll random(ll n)
{
    return (ll)((double)rand()/RAND_MAX*n+0.5);
}

ll multi(ll a,ll b,ll m)
{
    ll ans = 0;
    while(b>0)
    {
        if(b&1)
        {
            ans=(ans+a)%m;
        }
        b>>=1;
        a=(a<<1)%m;
    }
    return ans;
}

ll quick_mod(ll a,ll b,ll m)
{
    ll ans = 1;
    while(b)
    {
        if(b&1)
        {
            ans = multi(ans,a,m);
            //ans=ans*a%m;
        }
        b>>=1;
        a = multi(a,a,m);
        //a=a*a%m;
    }
    return ans;
}

bool Witness(ll a,ll n)
{
    ll m = n-1;
    int j=0;
    while(!(m&1))
    {
        j++;
        m>>=1;
    }
    ll x = quick_mod(a,m,n);    //a^(n-1)%n
    if(x==1 || x==n-1)
        return false;
    while(j--)
    {
        x = x*x%n;
        if(x == n-1)
            return false;
    }
    return true;
}

bool miller_rabin(ll n)
{
    if(n<2) return false;
    if(n==2) return true;
    if( !(n&1) ) return false;
    for(int i=1;i<=Times;i++)
    {
        ll a = random(n-2)+1;
        if(Witness(a,n)) return false;
    }
    return true;
}


int main()
{
    int p,T;
    cin>>T;
    while(T--)
    {
        cin>>p;
        ll n;
        n=(ll)1<

你可能感兴趣的:(数论)