Miller-Rabin素数测试

给出一个小于1e18的数,问它是否为质数?不超过50组询问。hihocoder

我是真的菜,为了不误导他人,本篇仅供个人使用。

首先,一个1e18的数,朴素\(O(\sqrt{n})\)素数判定肯定爆炸。怎么办呢?

我们知道,对于素数p,只要a不是p的倍数,一定有\(a^{p-1}=1\mod p\)。那么,我们是不是可以选出某些a,对于要判定的数p,看看他是否满足以a为底的费马小定理,以此来判定质数呢?答案是基本可以。

但是很不巧,有一类合数,以任何小于它们的质数为底进行判定,结果都是正确的。它们叫做伪素数。怎么排除伪素数的情况呢?有个叫做二次探测定理的东西:若\(x^2=1\mod p\),那么\(或x=1或-1\mod p\)。

假设\(a^{x-1}=1\mod p\)成立。如果x-1为奇数,就不再判定下去。否则,根据二次探测定理,还可以继续去判定\(或a^{\frac{x-1}{2}}=1或-1\mod p\)是否成立。如果它不等于1或-1,就返回false。如果它等于-1,就返回true。如果它等于1,就继续判定下去。反正,只要x-1为偶数,并且\(a^{x-1}=1\mod p\),就可以一直判定。这样就可以把那些伪素数排除掉了。这就叫做miller-rabin素数测试。据说选前7个质数作为a,在1e18内也只有两三个会被miller-rabin判定成素数的合数。

#include <cstdio>
using namespace std; typedef long long LL;
const LL m=7, a[m]={2, 3, 5, 7, 11, 13, 17};
LL n, p; LL fmul(LL a, LL b, LL p){ //将b分解为二进制,返回a*b%p
LL ans=0;
for (; b; b>>=1, a+=a, a%=p)
if (b&1) ans+=a, ans%=p;
return ans;
} LL fpow(LL a, LL x, LL p){
LL ans=1, base=a;
for (; x; x>>=1, base=fmul(base, base, p))
if (x&1) ans=fmul(ans, base, p);
return ans;
} bool MR(LL a, LL x, LL p){ //判断是否a^x=1或p-1 (mod p),且mr下去也成立
LL t=fpow(a, x, p);
if (t!=1&&t!=p-1) return false;
if (t==1&&x&1||t==p-1) return true;
return MR(a, x>>1, p);
} bool isprime(LL p){
if (p&1==0) return false;
for (LL i=0; i<m; ++i){
if (p==a[i]) return true; //互质时费马小定理才成立
if (fpow(a[i], p-1, p)!=1) return false;
if (!MR(a[i], (p-1)>>1, p)) return false;
}
return true;
} int main(){
scanf("%lld", &n);
while (n--){
scanf("%lld", &p);
puts(isprime(p)?"Yes":"No");
}
return 0;
}

Miller-Rabin素数测试的更多相关文章

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

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

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

  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. Miller Rabin素数检测与Pollard Rho算法

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

  6. Miller Rabin素数检测

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

  7. Miller Rabbin素数测试

    步骤 ①先写快速幂取模函数 ②MR算法开始 (1)传入两个参数一个是底数一个是n也就是幂数,如果n是一个合数那么可以判定,这个数一定不是素数 (2)然后开始寻找一个奇数的n去计算,如果最后满足a^d% ...

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

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

  9. 与数论的厮守01:素数的测试——Miller Rabin

    看一个数是否为质数,我们通常会用那个O(√N)的算法来做,那个算法叫试除法.然而当这个数非常大的时候,这个高增长率的时间复杂度就不够这个数跑了. 为了解决这个问题,我们先来看看费马小定理:若n为素数, ...

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

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

随机推荐

  1. java中i/o练习

    总结: FileInputStream fis; int length; while((length=fis.read(b,0,b.length))!=-1){ output.write(b,0,le ...

  2. java代码字符字节流

    总结: package com.aini; import java.io.IOException; import java.io.InputStreamReader; //流类 import java ...

  3. Spark Streaming之一:整体介绍

    提到Spark Streaming,我们不得不说一下BDAS(Berkeley Data Analytics Stack),这个伯克利大学提出的关于数据分析的软件栈.从它的视角来看,目前的大数据处理可 ...

  4. MyBatis基于注解----增删改查

    select sysdate from dual; --账户表 --账户编号,账户卡号,账户密码,账户余额,账户状态,创建时间 drop table account; create table acc ...

  5. python学习笔记(二):python数据类型

    上一篇博客写了python的入门和简单流程控制,这次写python的数据类型和各种数据类型的内置方法.一.数据类型是什么鬼?计算机顾名思义就是可以做数学计算的机器,因此,计算机程序理所当然地可以处理各 ...

  6. Changing Controller Numbers in Solaris

    If you need to change the controller numbers (c#) that a disk has assigned to it, whether it is for ...

  7. ABP仓储

    简介 我们都知道ABP已经实现了仓储模式,支持EF core 和dapper 进行数据库的连接和管理,可以很方便的注入仓储来操作你的数据,不需要自己单独定义一个仓储来实现,通用的仓储实现了通用的cru ...

  8. leetcode443

    使用两个数组分别记录字符和对应的数字,然后清除原来的vector,重新向里面添加元素.注意判断1个字符时,不将'1'加入vector. int compress(vector<char>& ...

  9. C语言学习笔记--递归函数

    1. 递归函数的思想 (1)递归是一种数学上分而自治的思想,是将大型复杂问题转化为与原问题相同但规模较小的问题进行处理的一种方法 (2)递归需要有边界条件 ①当边界条件不满足时,递归继续进行 ②当边界 ...

  10. [Elasticsearch2.x] 多字段搜索 (三) - multi_match查询和多数字段 <译>

    multi_match查询 multi_match查询提供了一个简便的方法用来对多个字段执行相同的查询. NOTE 存在几种类型的multi_match查询,其中的3种正好和在“了解你的数据”一节中提 ...