Miller-Rabin素数检测算法

其基于以下两个定理。

  1. Fermat小定理

    若n是素数,则∀a(a̸≡0(modn))\forall a(a \not\equiv 0 \pmod{n})∀a(a̸​≡0(modn)),有an−1≡1(modn)a^{n-1} \equiv 1 \pmod{n}an−1≡1(modn).

  2. 二次探测定理

    若n是素数,则x2≡1(modn)x^2 \equiv 1 \pmod{n}x2≡1(modn)只有平凡根x=±1x=\pm1x=±1,即x=1,x=n−1x=1,x=n-1x=1,x=n−1.

费马小定理鼎鼎有名,而二次探测定理由ZpZ_pZp​是域,域中无零因子容易得到。

注意这两个定理都是叙述了素数的必要条件,而Miller-Rabin对于要检验的n,是选取若干个a,检验是否满足这两个必要条件。显然,如果某个必要条件不满足,那么断言不是素数是正确的。但是,选了好几个a,都满足这两个必要条件,n是质数还是合数是无法确定的,但是Miller-Rabin算法选择忽略这一点,直接断言n是素数。

换句话说,Miller-Rabin算法断言一个数不是素数一定是正确的,断言一个数是素数,则可能是错误的。但是,实际上,会被误判为素数的合数,是很少的。而且每选取一个符合条件的a,通过检验出错的概率不超过12\frac{1}{2}21​.因此实际应用中使用Miller-Rabin算法是可行的。

实际上,选取一个a,仅仅基于费马小定理给出的必要条件做断言的检测算法,被错误断言为素数的合数称作基于a的伪素数

而通过选取各个符合条件的a,仅仅基于费马小定理,进行断言的检测算法,被错误断言为素数的伪素数就是卡迈克尔数

具体算法

假设nnn是奇数,令n=m×2q(q≥1)n=m \times 2^q (q \geq 1)n=m×2q(q≥1),其中mmm是奇数.

对于序列am mod n,a2m mod n,a4m mod n,…,a2q×m mod na^m \bmod n, a^{2m} \bmod n, a^{4m} \bmod n,\ldots,a^{2^q \times m} \bmod nammodn,a2mmodn,a4mmodn,…,a2q×mmodn.

最后一项就是费马小定理中的an−1a^{n-1}an−1, 并且每一项都是前一项的平方。

我们一项一项往后计算。

  • 若当前项为1,后面每一项显然都是1。而根据二次探测定理,n是素数必须前面一项是1或n-1.如果不符合,断言不是素数;符合,断言是素数。

  • 若当前项不是1,暂时不断言,接着往后算。除非当前是最后一项了,那么断言不是素数。

当然,如果第一项是1,由于不存在二次探测的方程,所以不检验前面一项(或者认为前面一项符合条件)。

Code

使用了快速幂模和快速幂加模板mod_sys。下面代码只是miller-rabin核心代码。

 // 如果只是int范围内,可以将pow_v2改为pow,mlt改为普通乘法
bool miller_rabin(ll a, ll n, ll q, ll m, mod_sys& mod) {
a = mod.pow_v2(a, m);
bool is_ordinary = true;
for (int i = 0; i < q; ++i) {
if (a == 1) {
return is_ordinary;
} else {
is_ordinary = (a == n-1);
a = mod.mlt(a,a);
}
}
return (a==1)&&(is_ordinary); // 最后一项
} // 使用miller_rabin检测是否是素数
const int kCheckCnt = 8;
// 为了随机数
random_device rd;
mt19937_64 gen(rd());
bool miller_rabin(ll n) {
if (n == 2) return true;
if ((n <= 2) || (n&1^1)) return false;
// 2^q×m表示原本输入的n-1
ll m = n, q = 0;
do { m >>= 1; ++q; } while(m&1^1);
// 随机数生成,[1,n-1] 均匀分布
uniform_int_distribution<> dis(1, n-1);
mod_sys mod;
mod.set_mod(n);
for (int i = 0; i < kCheckCnt; ++i)
if (!miller_rabin(dis(gen), n, q, m, mod))
return false;
return true;
}

模板题推荐hdu2138

Miller-Rabin素数检测算法 acm模板的更多相关文章

  1. Miller Rabin素数检测与Pollard Rho算法

    一些前置知识可以看一下我的联赛前数学知识 如何判断一个数是否为质数 方法一:试除法 扫描\(2\sim \sqrt{n}\)之间的所有整数,依次检查它们能否整除\(n\),若都不能整除,则\(n\)是 ...

  2. Miller Rabin素数检测

    #include<iostream> #include<cstdio> #include<queue> #include<cstring> #inclu ...

  3. POJ1811_Prime Test【Miller Rabin素数测试】【Pollar Rho整数分解】

    Prime Test Time Limit: 6000MS Memory Limit: 65536K Total Submissions: 29193 Accepted: 7392 Case Time ...

  4. POJ2429_GCD &amp; LCM Inverse【Miller Rabin素数測试】【Pollar Rho整数分解】

    GCD & LCM Inverse Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 9756Accepted: 1819 ...

  5. POJ1811_Prime Test【Miller Rabin素数測试】【Pollar Rho整数分解】

    Prime Test Time Limit: 6000MS Memory Limit: 65536K Total Submissions: 29193 Accepted: 7392 Case Time ...

  6. HDU1164_Eddy&#39;s research I【Miller Rabin素数测试】【Pollar Rho整数分解】

    Eddy's research I Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others ...

  7. Miller-Rabin素数检测算法

    遇到了一个题: Description: Goldbach's conjecture is one of the oldest and best-known unsolved problems in ...

  8. 关于素数:求不超过n的素数,素数的判定(Miller Rabin 测试)

    关于素数的基本介绍请参考百度百科here和维基百科here的介绍 首先介绍几条关于素数的基本定理: 定理1:如果n不是素数,则n至少有一个( 1, sqrt(n) ]范围内的的因子 定理2:如果n不是 ...

  9. 【数论基础】素数判定和Miller Rabin算法

    判断正整数p是否是素数 方法一 朴素的判定   

随机推荐

  1. GBM,XGBoost,LightGBM

    GBM如何调参:https://www.analyticsvidhya.com/blog/2016/02/complete-guide-parameter-tuning-gradient-boosti ...

  2. Ceph 13.2.8 三节点部署

    bs-k8s-ceph eth1 mon osd mgr deploy 2c2g sdb sdc sdd 各20G bs-hk-hk01 eth1 mon osd mgr 2c2g sdb sdc s ...

  3. Linux系统基础认知

    什么是操作系统? 操作系统作为接口的示意图: 没有安装操作系统的计算机,通常被称为裸机 如果想在 裸机 上运行自己所编写的程序,就必须用机器语言书写程序 如果计算机上安装了操作系统,就可以在操作系统上 ...

  4. Oracle 12C In-Memory特性研究

    Oracle 12C In-Memory特性研究一.Oracle In-Memory1.1 In-Memory 开启方法1.2 开启与关闭IM column store1.3 inmemory优先级调 ...

  5. pip安装了包但pycharm里找不到

    使用pip install scipy安装了scipy1.2.3,但是打开pycharm里import还是报错,打开pycharm设置,里面的解释器里也找不到所需的包. 原因:安装了anaconda, ...

  6. centos6.x下使用xinetd管理rsync服务

    系统环境说明:centos6.x,centos7.x下rsync直接可由systemd管理(无需使用xinetd). [root@meinv01 ~]# rpm -qa|grep xinetd [ro ...

  7. Java代码优化实践

    1.   尽量指定类的final修饰符 带有final修饰符的类是不可派生的.指定一个类为final,则该类所有方法都是final.Java编译器会会找机会内联所有否final方法,这样能够使性能平均 ...

  8. 配置 Apache James 邮件服务器以使用加密邮件通讯协议

    可先参照: 使用 Apache James 3.3.0(开源免费) 搭建内网电子邮件服务器(基于 Windows + Amazon Corretto 8)https://www.cnblogs.com ...

  9. 阿里云服务器Web Deploy配置和使用Visual Studio进行Web项目发布部署遇到的坑

    阿里云的服务器一直闲着,烧着银子,当初花几千大洋开通,本想弄信息化的项目为所帮扶的贫困户脱贫助手,不想势单力薄,一直没有找到好的项目.最近大家都在众志成城抗击新肺疫情,于是又想能不能尽点自己的力量,于 ...

  10. 2python脚本在window编辑后linux不能执行的问题

    参考简书博主天道酬勤abcd python脚本在windows编辑后,在linux下执行提示 /usr/bin/python^M: bad interpreter: No such file or d ...