梅森素数应用 nefu 120
梅森素数
定义:
- 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))
推论:设p是素数,M(p)为第p个梅森数,则算法复杂度为O(n^3)
梅森素数 - nefu 120
思路:R.1 = 4;R.k = (R.k-1 ^ 2 - 2) % Mp;
如果R.p-1 == 0,则是梅森素数,否则不是。
特殊判断:p == 2,即Mp = 3是梅森素数。
#include <iostream> #include <cstdio> #include <cstring> #include <cstdlib> using namespace std; typedef long long ll; ll multi(ll a, ll b, ll m) { ll ret = 0; while(b>0) { if(b&1) { ret = (ret+a)%m; } b >>= 1; a = (a<<1)%m; } return ret; } int main() { ll sum = 1, data[66], tmp; int n, p; data[1] = 4; cin >> n; while(n--) { sum = 1; cin >> p; sum <<= p; sum -= 1; for(int i = 2; i <= p-1; i++) { tmp = multi(data[i-1],data[i-1],sum); data[i] = (tmp-2)%sum; } if(p == 2) cout << "yes" << endl; else { if(data[p-1] == 0) cout << "yes" <<endl; else cout << "no" << endl; } } return 0; }
模板:
long long multi(long long a, long long b, long long m){//实现a * b % m的操作,用2 * 3 = 6模拟一下就懂了 long long ans = 0; while(b > 0){ if(b & 1) ans = (ans+a) % m; b >>= 1; a = (a<<1) % m; } return ans; } //判断是否是梅森素数 bool is_msPrime(int p){ long long r[70]; long long m = 1; m <<= p; m -=1;//求出Mp; r[1] = 4LL; if(p == 2) return true; for(int i = 2; i <= p-1; ++i) r[i] = (multi(r[i-1],r[i-1],m)-2) % m; if(r[p-1] == 0) return true; return false; }