定理:如果m是一个正整数,且2^m-1是一个素数,则m比是一个素数。
定义:如果m是一个正整数,且是素数而且
=2^m-1称作第m个梅森数,若
=2^m-1是一个素数,那么就称它是一个梅森素数。
判定方法:lucas-lehmer判定法
设p是一个素数,第p个个梅森数
,r[1]=4,对于k>=2,利用
r[k]=r[k-1]^1-2(mod
)
0=<r[k]<
可以得到r的序列,则有
是素数,当且仅当r[p-1]=0(mod
)。
lucas-lehmer判定法模版:
bool lucas(long long x,long long n) //x=(1<<n)-1
{
long long tmp;
for(int i=2;i<n;i++)
{
tmp=data[i-1]*data[i-1];
data[i]=(tmp-2)%x;
}
if(n==2)
return true;
else if(data[n-1]==0) return true;
else return false;
}
例题:nefu 120 梅森素数
给定一个正整数n,求出第n个梅森数是否是梅森素数。
代码:
#include <iostream>
#include <cstdio>
using namespace std;
long long data[64];
long long multi(long long m,long long p) //因为给出的数的平方可能会溢出
{ //所以选择将乘法取余转化成加法取余
if(m<0) m=-m;
long long n=m;
long long t=0;
while(n)
{
if(n&1) t=(t+m)%p;
n>>=1;
m=(m<<1)%p;
}
return t;
}
bool lucas(long long x,long long n)
{
long long tmp;
for(int i=2;i<n;i++)
{
tmp=multi(data[i-1],x);
data[i]=(tmp-2)%x;
}
if(n==2)
return true;
else if(data[n-1]==0) return true;
else return false;
}
int main()
{
int n;
cin>>n;
while(n--)
{
data[1]=4;
long long x,m=1;
cin>>x;
m=(m<<x)-1;
//cout<<x<<" "<<m<<endl;
if(lucas(m,x)) printf("yes\n");
else printf("no\n");
}
return 0;
}
原文地址:http://blog.csdn.net/u010650359/article/details/27827487