梅森素数应用 nefu 120

梅森素数

定义:

  • if m是一个正整数 and 2^m-1是一个素数 then m是素数
  • if m是一个正整数 and m是一个素数 then M(m)=2^m-1被称为第m个梅森数
  • if p是一个素数 and M(p)是一个素数 then M(p)被称为梅森素数

Lucas-Lehmer判定法:判定一个梅森数是否是梅森素数

设p是素数,第p个梅森数为M(p)为2^p-1,r1 = 4,对于k >= 2

r(k) = r(k+1)^2-2(modM(p)), 0 <= r(k) <= M(p)

可以得到r(k)序列,则有M(p)是素数,当且仅当r(p-1) = 0(mod M(p))

推论:设p是素数,M(p)为第p个梅森数,则算法复杂度为O(n^3)

梅森素数 - nefu 120

思路:R.1 = 4;R.k = (R.k-1 ^ 2 - 2) % Mp;

如果R.p-1 == 0,则是梅森素数,否则不是。
特殊判断:p == 2,即Mp = 3是梅森素数。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>

using namespace std;
typedef long long ll;

ll multi(ll a, ll b, ll m)
{
    ll ret = 0;
    while(b>0)
    {
        if(b&1)
        {
            ret = (ret+a)%m;
        }
        b >>= 1;
        a = (a<<1)%m;
    }
    return ret;
}
int main()
{
    ll sum = 1, data[66], tmp;
    int n, p;
    data[1] = 4;
    cin >> n;
    while(n--)
    {
        sum = 1;
        cin >> p;
        sum <<= p;
        sum -= 1;
        for(int i = 2; i <= p-1; i++)
        {
            tmp = multi(data[i-1],data[i-1],sum);
            data[i] = (tmp-2)%sum;
        }
        if(p == 2)
            cout << "yes" << endl;
        else
        {
            if(data[p-1] == 0)
                cout << "yes" <<endl;
            else
                cout << "no" << endl;
        }
    }
    return 0;
}

模板:

long long multi(long long a, long long b, long long m){//实现a * b % m的操作,用2 * 3 = 6模拟一下就懂了
    long long ans = 0;
    while(b > 0){
        if(b & 1)  ans = (ans+a) % m;
        b >>= 1;
        a = (a<<1) % m;
    }
    return ans;
}
//判断是否是梅森素数
bool is_msPrime(int p){
    long long r[70];
    long long m = 1;
    m <<= p;  m -=1;//求出Mp;
    r[1] = 4LL;
    if(p == 2)  return true;
    for(int i = 2; i <= p-1; ++i)
        r[i] = (multi(r[i-1],r[i-1],m)-2) % m;
    if(r[p-1] == 0)  return true;
    return false;
}