算法简介

Miller-Rabin算法,这是一个很高效的判断质数的方法,可以在用\(O(logn)\) 的复杂度快速判断一个数是否是质数。它运用了费马小定理和二次探测定理这两个筛质数效率极高的方法。

费马小定理判质数

\(a^{p - 1}\ ≡\ 1\ mod\ p\)

这个定理在 \(p\) 为质数的时候是成立的,所以我们可以如果要判断 \(p\) 是否是质数,可以 \(rand\) 几个 \(a\) 值然后照着这个式子来算,如果算出来不是 \(1\) 那说明 \(p\) 一定不是质数。

但在我们的自然数中,如果照着这个式子算出来的答案为1,也是有可能不是质数的。更有一类合数,它用费马小定理不管 rand 什么数都判不掉。这类合数称为 Carmichael数(卡迈克尔数),其中一个例子就是561(哇,居然这么小)。

二次探测定理

因为Carmichael数的存在,使得我们难以高效判断质数,所以我们还需要加入第二种判断方法使这种伪算法更优秀!而二次探测无疑就是为我们量身定制的算法,因为它要建立在同余式右边为1的基础上(而我们的费马小定理不正好满足了要求吗?)

若 \(b^2≡1\ mod\ p\) 且 \(p\) 为质数 \(=>\) 则 \(p\) 一定可以被 \(b−1\) 和 \(b+1\) 其中一个整除

这是二次探测定理,原理很简单,我们将上面的同余式左右都减1,根据平方差公式可以得出 \((b−1)(b+1)≡\ 0\ mod\ p\) 这其实就代表着等式左边是模数的倍数,但若模数p是质数,则 \((b−1)\) 和 \((b+1)\) 必定存在一个是 \(p\) 的倍数,所以要么 \(b−1=p\ (b=1)\) 或者 \(b+1=p\ (b=p−1)\) 如果不满足则 \(p\) 一定不是质数!然后我们还可以发现若 \(b=1\) 我们又可以进行新一轮二次探测!

根据这个道理,我们可以进行二次探测:因为 \(a^{p−1}≡1\mod\ p\) 如果 \(p−1\) 为偶数的话就可以化成: \(a^{(\frac{p−1}2)^2}≡1\ mod\ p\) 这样就变成了二次探测的基本式。

typedef long long ll;
typedef unsigned long long ull;
typedef long double lb;
inline ll ksc(ull x, ull y, ll p) { // O(1)快速乘(防爆long long)
return (x * y - (ull)((lb)x / p * y) * p + p) % p;
} inline ll ksm(ll x, ll y, ll p) { //快速幂
ll res = 1;
while (y) {
if (y & 1) res = ksc(res, x, p);
x = ksc(x, x, p);
y >>= 1;
}
return res;
} inline bool mr(ll x, ll p) {
if (ksm(x, p - 1, p) != 1) return 0; //费马小定理
ll y = p - 1, z;
while (!(y & 1)) { //一定要是能化成平方的形式
y >>= 1;
z = ksm(x, y, p); //计算
if (z != 1 && z != p - 1) return 0; //不是质数
if (z == p - 1) return 1; //一定要为1,才能继续二次探测
}
return 1;
} inline bool prime(ll x) {
if (x < 2) return 0;
if (x == 2 || x == 3 || x == 5 || x == 7 || x == 43) return 1;
return mr(2, x) && mr(3, x) && mr(5, x) && mr(7, x) && mr(43, x);
}

这样子加上二次探测之后,明显就能高效很多,基本上卡不了,大概要每 \(10^{10}\) 个数才会出现一个判不掉的,这个概率可以说十分微小,可以忽略!

Miller-Rabin 素数检验算法的更多相关文章

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

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

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

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

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

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

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

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

  5. 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 ...

  6. Miller Rabin素数检测

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

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

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

  8. GCDLCM 【米勒_拉宾素数检验 (判断大素数)】

    GCDLCM 题目链接(点击) 题目描述 In FZU ACM team, BroterJ and Silchen are good friends, and they often play some ...

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

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

随机推荐

  1. dhtmlxGantt独立安装的系统要求

    dhtmlxGantt库提供了使用导出作为在线服务从甘特图导出和导入数据的可能性. 您还可以通过在计算机上安装导出服务来本地导出甘特图.您需要确保系统满足系统要求才能使用导出模块: PNG / PDF ...

  2. 安卓app功能或自动化测试覆盖率统计(不用instrumentation启动app)

    一文带你揭秘如何采取非instrumentation启动app,打造实时统计覆盖率,一键触发覆盖率测试报告. 在上篇文章,一文带你解决Android app手工测试或者自动化测试覆盖率统计(撸代码版) ...

  3. 092 01 Android 零基础入门 02 Java面向对象 02 Java封装 01 封装的实现 03 # 088 01 Android 零基础入门 02 Java面向对象 02 Java封装 02 static关键字 02 static关键字(中)

    092 01 Android 零基础入门 02 Java面向对象 02 Java封装 01 封装的实现 03 # 088 01 Android 零基础入门 02 Java面向对象 02 Java封装 ...

  4. Java知识系统回顾整理01基础02面向对象02属性

    一.根据实例给出"属性"的定义 一个英雄有姓名,血量,护甲等等状态 这些状态就叫做一个类的属性 二.属性的类型 属性的类型可以是基本类型,比如int整数,float 浮点数 也可以 ...

  5. VID和PID

    今天很在一份datasheet上突然看到 VID 和 PID 很奇怪!!还不是很懂!!! 参考:https://blog.csdn.net/gaojinshan/article/details/787 ...

  6. Arduino各开发板

    参考来源:https://www.arduino.cn/thread-42417-1-1.html 查了好久,发现除了奈何等等几位大神总结过arduino各板子之间的性能.差异,没有很新的分析文章,在 ...

  7. java进阶(26)--ForEach

    JDK5.0后新特性 一.普通for循环

  8. BeetleX之webapi自定义响应内容

    输出内容多样性在webapi服务中比较普遍的,有的情况使用json,xml,图片和二进制流下载等等:为了适应用不同情况的需要,组件支持自定义内容输出.接下来的主要描述组件在webapi如何定义各种内容 ...

  9. Jmeter请求之接口串联自动化测试(未完)

    方案一:添加Cookie管理器,把用户的登录状态存在cookie管理器中,类似于浏览器 存储测试结果: 监听器->保存响应到文件,对结果进行存储 文件名前缀:保存到哪个地方前缀是什么D:\tes ...

  10. 【C语言教程】“双向循环链表”学习总结和C语言代码实现!

    双向循环链表 定义 双向循环链表和它名字的表意一样,就是把双向链表的两头连接,使其成为了一个环状链表.只需要将表中最后一个节点的next指针指向头节点,头节点的prior指针指向尾节点,链表就能成环儿 ...