梅森素数 判定总结 - Lucas-Lehmer算法 & Miller-rabin算法
梅森素数
定义:
- 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;
}
Miller-rabin 素数测试:直接判断M(p)是不是素数
理论知识:
费马小定理: 对于素数p和任意整数a,有ap ≡ a(mod p)(同余)。反过来,满足ap ≡ a(mod p),p也几乎一定是素数。
伪素数: 如果n是一个正整数,如果存在和n互素的正整数a满足 an-1 ≡ 1(mod n),我们说n是基于a的伪素数。如果一个数是伪素数,那么它几乎肯定是素数。
Miller-Rabin测试: 不断选取不超过n-1的基b(s次),计算是否每次都有bn-1 ≡ 1(mod n),若每次都成立则n是素数,否则为合数。
还有一个定理,能提高Miller测试的效率:
二次探测定理: 如果p是奇素数,则 x2 ≡ 1(mod p)的解为 x = 1 || x = p - 1(mod p);
两个高效求解a*b%m a^b%m的方法
// a * b % n
//例如: b = 1011101那么a * b mod n = (a * 1000000 mod n + a * 10000 mod n + a * 1000 mod n + a * 100 mod n + a * 1 mod n) mod n
ll mod_mul(ll a, ll b, ll n) {
ll res = 0;
while(b) {
if(b&1) res = (res + a) % n;
a = (a + a) % n;
b >>= 1;
}
return res;
}
//a^b % n
//同理
ll mod_exp(ll a, ll b, ll n) {
ll res = 1;
while(b) {
if(b&1) res = mod_mul(res, a, n);
a = mod_mul(a, a, n);
b >>= 1;
}
return res;
}
代码如下:
bool miller_rabin(ll n) {
if(n == 2 || n == 3 || n == 5 || n == 7 || n == 11) return true;
if(n == 1 || !(n%2) || !(n%3) || !(n%5) || !(n%7) || !(n%11)) return false;
ll x, pre, u;
int i, j, k = 0;
u = n - 1; //要求x^u % n
while(!(u&1)) { //如果u为偶数则u右移,用k记录移位数
k++; u >>= 1;
}
srand((ll)time(0));
for(i = 0; i < S; ++i) { //进行S次测试
x = rand()%(n-2) + 2; //在[2, n)中取随机数
if((x%n) == 0) continue;
x = mod_exp(x, u, n); //先计算(x^u) % n,
pre = x;
for(j = 0; j < k; ++j) { //把移位减掉的量补上,并在这地方加上二次探测
x = mod_mul(x, x, n);
if(x == 1 && pre != 1 && pre != n-1) return false; //二次探测定理,这里如果x = 1则pre 必须等于 1,或则 n-1否则可以判断不是素数
pre = x;
}
if(x != 1) return false; //费马小定理
}
return true;
}
梅森素数 判定总结 - Lucas-Lehmer算法 & Miller-rabin算法的更多相关文章
- Pollard rho算法+Miller Rabin算法 BZOJ 3668 Rabin-Miller算法
BZOJ 3667: Rabin-Miller算法 Time Limit: 60 Sec Memory Limit: 512 MBSubmit: 1044 Solved: 322[Submit][ ...
- 【数论基础】素数判定和Miller Rabin算法
判断正整数p是否是素数 方法一 朴素的判定
- Miller Rabin算法详解
何为Miller Rabin算法 首先看一下度娘的解释(如果你懒得读直接跳过就可以反正也没啥乱用:joy:) Miller-Rabin算法是目前主流的基于概率的素数测试算法,在构建密码安全体系中占有重 ...
- Miller Rabin 算法简介
0.1 一些闲话 最近一次更新是在2019年11月12日.之前的文章有很多问题:当我把我的代码交到LOJ上,发现只有60多分.我调了一个晚上,尝试用{2, 3, 5, 7, 11, 13, 17, 1 ...
- Miller Rabin算法学习笔记
定义: Miller Rabin算法是一个随机化素数测试算法,作用是判断一个数是否是素数,且只要你脸不黑以及常数不要巨大一般来讲都比\(O(\sqrt n)\)的朴素做法更快. 定理: Miller ...
- (Miller Rabin算法)判断一个数是否为素数
1.约定 x%y为x取模y,即x除以y所得的余数,当x<y时,x%y=x,所有取模的运算对象都为整数. x^y表示x的y次方.乘方运算的优先级高于乘除和取模,加减的优先级最低. 见到x^y/z这 ...
- Miller-Rabin算法 codevs 1702 素数判定 2
转载自:http://www.dxmtb.com/blog/miller-rabbin/ 普通的素数测试我们有O(√ n)的试除算法.事实上,我们有O(slog³n)的算法. 定理一:假如p是质数,且 ...
- Miller Rabin素数检测与Pollard Rho算法
一些前置知识可以看一下我的联赛前数学知识 如何判断一个数是否为质数 方法一:试除法 扫描\(2\sim \sqrt{n}\)之间的所有整数,依次检查它们能否整除\(n\),若都不能整除,则\(n\)是 ...
- poj 1811 Pallor Rho +Miller Rabin
/* 题目:给出一个数 如果是prime 输出prime 否则输出他的最小质因子 Miller Rabin +Poller Rho 大素数判定+大数找质因子 后面这个算法嘛 基于Birthday Pa ...
随机推荐
- CentOS 部署openVPN
一.openVPN工作原理 VPN技术通过密钥交换.封装.认证.加密手段在公共网络上建立起私密的隧道,保障传输数据的完整性.私密性和有效性.OpenVPN是近年来新出现的开放源码项目,实现了SSLVP ...
- python基础-第十一篇-11.2DOM为文档操作
文档对象模型(DOM)是一种用于HTML和XML文档的编程接口 节点类型 12种节点类型都有NodeType属性来表明节点类型 节点关系 <div id="t"> &l ...
- Python并行编程(八):with语法
1.基本概念 当有两个相关的操作需要在一部分代码块前后分别执行的时候,可以使用with语法自动完成.同时,使用with语法可以在特定的地方分配和释放资源,因此,with语法也叫作"上下文管理 ...
- 每人涨10%的工资,涨的前一共不超过5万,从低工资往高工资的人涨,超过5W则停止涨,问涨的钱花了多少,多少人获得了涨薪。
;with test(CID,money,NewAmount) as ( SELECT Row_Number() over ( order by money ) as CID ,money ,mone ...
- 20165324 实验二《Java面向对象程序设计》实验报告
20165324 实验二<Java面向对象程序设计>实验报告 一.实验报告封面 课程:Java程序设计 班级:1653班 姓名:何春江 学号:20165324 指导教师:娄嘉鹏 实验日期: ...
- win8.1 设置默认输入法为英文
win8.1中文版 输入法默认为微软拼音且为中文,此事在使用类似cmd就很不方便了,这里我们只需要将输入法设置为 “允许我为每个应用窗口设置不同的输入法”即可,操作如下:
- Jackson /常用注解/ annotation(转)
1.@JsonAutoDetect 自动检测,(作用在类上)来开启/禁止自动检测. fieldVisibility:字段的可见级别 ANY:任何级别的字段都可以自动识别 NONE:所有字段都不可以自动 ...
- Maven详解(转)
原文出自: http://www.cnblogs.com/hongwz/p/5456578.html http://ifeve.com/maven-1/ Maven介绍: Maven是一个强大的Jav ...
- vue的ref与$refs
一. ref使用在父组件上 父组件html: <information ref='information'></information> import information ...
- android线程学习心得
有一篇关于android线程讲的非常好,大家可以参考下,其中有一句话讲的非常好,就拿来做开篇之句: 当一个程序第一次启动时,Android会同时启动一个对应的主线程(Main Thread),主线程主 ...