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. YUM源部署和使用

    1.前言 为什么需要内部yum源呢,有可能是业务内部的服务器对外是不通了,居于一些安全方面的考虑.内部yum源又有什么好处呢,第一,速度快:第二,内网可控,外网有问题也不影响内网包的下载和安装等. 2 ...

  2. 云服务器InfluxDB & Chronograf配置

    环境: 阿里云服务器 Ubuntu 18.04.3 LTS InfluxDB 1.7.10 (截至2020.2.20最新版) chonograf 1.8.0 (2020.2.19推出) 配置建议: 不 ...

  3. 13-Servlet&Request

    今日内容: 1. Servlet 2. Request Servlet 1. 概念 2. 步骤 3. 执行原理 4. 生命周期 5. Servlet3.0注解配置 6. Servlet的体系结构 se ...

  4. Java类的加载过程与ClassLoader的理解及测试

    当程序准备运行某个类,但该类还未被加载到内存中时,会经过以下三个步骤进行类的加载: 类的加载(Load)→类的连接(Link)→类的初始化(Initialize) 加载:类经过javac.exe编译的 ...

  5. SpringBoot嵌入式Servlet配置原理

    SpringBoot嵌入式Servlet配置原理 SpringBoot修改服务器配置 配置文件方式方式修改,实际修改的是ServerProperties文件中的值 server.servlet.con ...

  6. Tensorflow和pytorch安装(windows安装)

    一. Tensorflow安装 1. Tensorflow介绍 Tensorflow是广泛使用的实现机器学习以及其它涉及大量数学运算的算法库之一.Tensorflow由Google开发,是GitHub ...

  7. centos7.5下yum安装nginx-1.14.2

    rpm -Uvh http://nginx.org/packages/centos/7/noarch/RPMS/nginx-release-centos-7-0.el7.ngx.noarch.rpm ...

  8. centos6.5和centos7.5统一字符集为zh_CN.UTF-8解决系统和MySQL数据库乱码问题

    linux的服务器需要做的操作 centos6.5下: 修改默认字符集为 zh_CN.UTF-8,如果没有中文语言包可能需要安装中文语言包支持 [root@meinv01 ~]# yum groupi ...

  9. Force removing ActivityRecord no saved state问题的原因分析

    关键字,crash Force removing ActivityRecord,app died, no saved state的原因 相机拍摄的过程中断电,拍了一张黑图 I/ActivityMana ...

  10. 杭电-------2047阿牛的eof牛肉串(C语言写)

    /* 主要看最后一个是否为O,若为O,则倒数第二个不能为O,则为a[n-2]*1*2; 若不为O,则最后一个有两个选择则为a[n-1]*2 */ #include<stdio.h> ] = ...