梅森素数
定义:
- if m是一个正整数 and 2^m-1是一个素数 then m是素数
- if m是一个正整数 and m是一个素数 then M(m)=2^m-1被称为第m个梅森数
- if p是一个素数 and M(p)是一个素数 then M(p)被称为梅森素数
Lucas-Lehmer判定法:判定一个梅森数是否是梅森素数
设p是素数,第p个梅森数为M(p)为2^p-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))
代码如下
#include<iostream>
#include<vector>
using namespace std;
/*
利用Lucas-Lehmer方法判断梅森素数
*/
long long multi(long long a, long long b, long long sum)//a*b%sum与快速幂原理相同
{
long long ret = 0;
while (b > 0)
{
if (b & 1)
{
ret = (ret + a) % sum;
}
b >>= 1;
a = (a << 1) % sum;
}
return ret;
}
int main()
{
long long rk[99];
rk[1] = 4;
long long sum = 1;
long long temp;
int p;
int n;
cin >> n;
while (n--)
{
sum = 1;
cin >> p;
sum <<= p;
sum -= 1;
cout << sum << endl;
if (p == 2)//对于p==2特殊判断
{
cout << "yes" << endl;
continue;
}
for (int i = 2; i < p; i++)
{
temp = multi(rk[i - 1], rk[i - 1],sum);
rk[i] = (temp - 2) % sum;
}
if (rk[p - 1] == 0)
{
cout << "yes" << endl;
}
else
{
cout << "no" << endl;
}
}
system("pause");
return 0;
}
miller算法
费马小定理
费马小定理就是说如果p是一个质数,而整数a不是p的倍数,则有a^(p-1)≡1(mod p)。也可以写做a^p ≡ p (mod p).
二次探测
如果p是一个素数,那么使得x2 ≡ 1 (mod p)的 x的解只有两种可能,就是x = 1 或者 x = p-1
代码如下
#include<iostream>
#include<vector>
#include<time.h>
using namespace std;
/*
miller方法求梅森素数
*/
long long random1(long long n)
{
return (long long)((double)rand() / RAND_MAX*n + 0.5);
}
long long mul(long long a, long long b, long long m)
{
int ans = 1;
while (b > 0)
{
if (b & 1)
{
ans = (ans + a) % m;
}
a <<= 1;
a = a%m;
b >>= 1;
}
return ans;
}
long long quick_mod(long long a, long long b, long long m)
{
long long ans = 1;
while (b > 0)
{
if (b & 1)
{
ans = ans*a%m;
}
a = a*a%m;
b >>= 1;
}
return ans;
}
bool miller(int n)
{
int m = n - 1;
int t = 0;
if (n < 2)
return false;
if (n == 2)
return true;
if (!(n & 1))
return false;
while (!(m & 1))
{
m >>= 1;
t++;
}
for (int i = 0; i < 20; i++)
{
long long a = random1(n);
long long x = (a, m, n);
long long y;
for (int j = 0; j < t; j++)
{
y = quick_mod(x, x, n);
if (y == 1 && x != 1 && x != n - 1)
return false;
x = y;
}
if (x != 1)
return false;
}
return true;
}
void main()
{
cout << miller(8) << endl;
system("pause");
}