梅森素数

定义:Mp=2p-1,当p为素数,且Mp为素数,则称Mp为梅森素数

当p为第几个素数,则称Mp为第几个梅森数

判定:

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

设p是素数,第p个梅森数为Mp为2p-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))

涉及知识:

卢卡斯-莱默检验法原理

假设我们想验证M3 = 7是素数。我们从s=4开始,并更新3−2=1次,把所有的得数模7:
  • s ← ((4 × 4) − 2) mod 7 = 0
由于我们最终得到了一个能被7整除的s,因此M3是素数。
另一方面,M11 = 2047 = 23 × 89就不是素数。我们仍然从s=4开始,并更新11−2=9次,把所有的得数模2047:
  • s ← ((4 × 4) − 2) mod 2047 = 14
  • s ← ((14 × 14) − 2) mod 2047 = 194
  • s ← ((194 × 194) − 2) mod 2047 = 788
  • s ← ((788 × 788) − 2) mod 2047 = 701
  • s ← ((701 × 701) − 2) mod 2047 = 119
  • s ← ((119 × 119) − 2) mod 2047 = 1877
  • s ← ((1877 × 1877) − 2) mod 2047 = 240
  • s ← ((240 × 240) − 2) mod 2047 = 282
  • s ← ((282 × 282) − 2) mod 2047 = 1736
由于s最终仍未能被2047整除,因此M11=2047不是素数。但是,我们从这个检验法仍然无法知道2047的因子,只知道它的卢卡斯-莱默余数1736。
思路:输入p,先求出2p-1,循环求r(k) = (r(k-1)2-2)%Mp
while((p--) > 2)
{
    r=(mul(r,r,n)-2+n)%n;
}

if(r % n == 0)
    puts("yes");
else
    puts("no");
View Code

 

题目大意:输入一个p,判断Mp是否为梅森素数,是输出"yes"不是输出"no"

#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;

typedef long long ll;

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

int main()
{
    int t, p;
    cin>>t;
    while(t--)
    {
        cin>>p;
        ll n=((ll)1<<p)-1;//计算2^10-1的值
        ll r=4;
        if(p == 2)
            puts("yes");//特判
        else
        {
            while((p--) > 2)
            {
                r=(mul(r,r,n)-2+n)%n;
            }

            if(r % n == 0)
                puts("yes");
            else
                puts("no");
        }
    }
    return 0;
}
View Code

 

posted @ 2019-07-18 10:11  窗子外和窗子里  阅读(1080)  评论(0编辑  收藏  举报