NEFU 120 梅森素数(梅森数素数判定--Lucas-Lehmer测试判定)

梅森素数

Problem : 120

Time Limit : 1000ms

Memory Limit : 65536K

description

由于梅森学识渊博,才华横溢,为人热情以及最早系统而深入地研究2p-1 型的数(其中p为素数),为了纪念他,数学界就把这种数称为“梅森数”;并以Mp 记之(其中M为梅森姓名的首字母),即Mp=2p-1 。如果梅森数为素数,则称之为“梅森素数”。 比如p=2,3,5,7时,Mp都是素数,但211-1 不是素数 。现在请你求出前N个梅森素数。

input

有多组测试数据。
第一行是一个正整数T,表示测试数据的组数。接下来每组1个数p的值,这里2<= p <= 62。

output

对于每组测试数据,判断Mp 是不是梅森素数,是就输出“yes ”,否就输出“no”,输出后要换行。

sample_input

2
2
7

sample_output

yes
yes




思路:显然n=2^p-1当p不是素数时n不是梅森数,显然不是素数(可以分解因式反证)

当p是素数即n是梅森数时,需要判定n是不是素数,可以用Lucas-Lehmer测试判定法


涉及知识:

卢卡斯-莱默检验法原理是这样:令梅森数 Mp = 2p− 1作为检验对象(预设p素数,否则Mp就是合数了)。定义序列{si }:所有的i ≥ 0

 s_i =\begin{cases}\;\;\,4 \\s_{i-1}^2-2 \end{cases},如果\displaystyle i = 0
,如果\displaystyle i > 0
.
.
.

这个序列的开始几项是41419437634, ... (OEIS中的数列A003010) 那么Mp是素数当且仅当

s_{p-2}\equiv0\pmod{M_p};

否则, Mp合数sp − 2Mp的余数叫做p卢卡斯-莱默余数


用程序算出Sp-2即可,要注意的是p=2时,不能用这个判定方法,特判一下即可


//Accepted 800k 4ms C++ (g++ 3.4.3) 692 
#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;

typedef long long ll;

ll T,p;
ll multi(ll a,ll b,ll mod)//手写乘法计算,因为直接乘会溢出long long
{
    ll ans=0;
    while(b)
    {
        if(b&1)
            ans=(ans+a)%mod;
        b>>=1;
        a=(a<<1)%mod;
    }
    return ans;
}
int main()
{
    scanf("%lld",&T);
    while(T--)
    {
        scanf("%lld",&p);
        ll n=((ll)1<<p)-1;
        ll r=4;
        if(p==2) puts("yes");//特判
        else
        {
            while((--p)!=1) r=(multi(r,r,n)-2+n)%n;
            if(r%n==0) puts("yes");
            else puts("no");
        }
    }
    return 0;
}



  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值