标签:
梅森素数 |
|||
|
|||
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
,如果; | |
,如果。 |
这个序列的开始几项是4, 14, 194, 37634, ... (OEIS中的数列A003010) 那么Mp是素数当且仅当
否则, Mp是合数。sp ? 2模Mp的余数叫做p的卢卡斯-莱默余数。
//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