码迷,mamicode.com
首页 > 其他好文 > 详细

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

时间:2015-04-04 09:24:06      阅读:312      评论:0      收藏:0      [点我收藏+]

标签:

梅森素数

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

技术分享 ,如果技术分享
,如果技术分享
.
.
.

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

技术分享

否则, 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;
}



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

标签:

原文地址:http://blog.csdn.net/kalilili/article/details/44857781

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!