Miiler-Robin素数测试与Pollard-Rho大数分解法
Miiler-Robin素数测试
目前已知分解质因数以及检测质数确定性方法就只能\(sqrt{n}\)试除
但是我们可以基于大量测试的随机算法而有大把握说明一个数是质数
Miler-Robin素数测试基于以下两个原理:
费马小定理
即我们耳熟能详的
对于质数\(p\)
\]
二次探测原理
对于质数\(p\),如果存在\(x\)满足
\]
那么\(x\)只能是\(1\)或者\(p - 1\)
由此我们便可以随机生成多个\(x\),逐一用以上两个原理检验即可
只要全都符合,我们就有大概\(1 - (\frac{1}{4})^{T}\)的把握说\(p\)是一个质数
具体操作时,令\(p = 2^{t}r + 1\),我们对于\(z = 2^{m}r\),其中\(m\)小于等于\(t\),都使用二次探测原理检验
最后再利用费马小定理检验
bool Miller_Rabin(LL n){
if (n == 2 || n == 3 || n == 5 || n == 7 || n == 11 || n == 13) return true;
if (n == 1 || n % 2 == 0 || n % 3 == 0 || n % 7 == 0 || n % 11 == 0 || n % 13 == 0) return false;
int T = 50;
LL t = n - 1,k = 0;
while (!(t & 1)) t >>= 1,k++;
while (T--){
LL x = qpow(random(n),t,n),y;
REP(i,k){
y = x,x = mul(x,x,n);
if (x == 1 && y != 1 && y != n - 1) return false;
}
if (x != 1) return false;
}
return true;
}
Pollard-Rho大数分解法
我们利用式子\(x^2 + c\)伪随机生成两个数\(a\)和\(b\),判断\(d = (a - b,n)\)是否大于\(1\)小于\(n\),如果是,我们便找打了一个\(n\)的因子\(d\),递归处理\(\frac{n}{d}\)和\(d\)即可,当我们使用以上的素数判定判定出\(n\)是质数时,计入答案
当然我们伪随机生成的两个数可能成环而导致死循环,我们用\(Floyd\)的大步小步法判环即可
具体看代码
LL pr[maxn],pi;
LL gcd(LL a,LL b){return b ? gcd(b,a % b) : a;}
LL Pollard_Rho(LL n){
LL x = random(n),y = x,c = random(n),step = 1,t = 2;
while (true){
step++; x = (mul(x,x,n) + c) % n;
if (y == x) return 1;
LL d = gcd((y - x + n) % n,n);
if (d > 1) return d;
if (step == t) y = x,t <<= 1;
}
}
void Find(LL n){
if (n == 1) return;
if (Miller_Rabin(n)) {pr[++pi] = n; return;}
LL p = n; while (p == n) p = Pollard_Rho(n);
Find(n / p); Find(p);
}
至此我们就可以写出POJ1811
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
#include<cmath>
#include<map>
#define Redge(u) for (int k = h[u],to; k; k = ed[k].nxt)
#define REP(i,n) for (int i = 1; i <= (n); i++)
#define mp(a,b) make_pair<int,int>(a,b)
#define cls(s) memset(s,0,sizeof(s))
#define cp pair<int,int>
#define LL long long int
using namespace std;
const int maxn = 100005,maxm = 100005;
const LL INF = 1000000000ll * 1000000000ll;
inline LL read(){
LL out = 0,flag = 1; char c = getchar();
while (c < 48 || c > 57){if (c == '-') flag = -1; c = getchar();}
while (c >= 48 && c <= 57){out = (out << 3) + (out << 1) + c - 48; c = getchar();}
return out * flag;
}
inline LL random(LL x){
LL re = 0;
REP(i,4) re = (re << 14) + rand();
return re % x;
}
inline LL mul(LL a,LL b,LL P){
LL re = 0;
for (; b; b >>= 1,a = (a + a) % P)
if (b & 1) re = (re + a) % P;
return re;
}
inline LL qpow(LL a,LL b,LL P){
LL re = 1;
for (; b; b >>= 1,a = mul(a,a,P))
if (b & 1) re = mul(re,a,P);
return re;
}
bool Miller_Rabin(LL n){
if (n == 2 || n == 3 || n == 5 || n == 7 || n == 11 || n == 13) return true;
if (n == 1 || n % 2 == 0 || n % 3 == 0 || n % 7 == 0 || n % 11 == 0 || n % 13 == 0) return false;
int T = 50;
LL t = n - 1,k = 0;
while (!(t & 1)) t >>= 1,k++;
while (T--){
LL x = qpow(random(n),t,n),y;
REP(i,k){
y = x,x = mul(x,x,n);
if (x == 1 && y != 1 && y != n - 1) return false;
}
if (x != 1) return false;
}
return true;
}
LL pr[maxn],pi;
LL gcd(LL a,LL b){return b ? gcd(b,a % b) : a;}
LL Pollard_Rho(LL n){
LL x = random(n),y = x,c = random(n),step = 1,t = 2;
while (true){
step++; x = (mul(x,x,n) + c) % n;
if (y == x) return 1;
LL d = gcd((y - x + n) % n,n);
if (d > 1) return d;
if (step == t) y = x,t <<= 1;
}
}
void Find(LL n){
if (n == 1) return;
if (Miller_Rabin(n)) {pr[++pi] = n; return;}
LL p = n; while (p == n) p = Pollard_Rho(n);
Find(n / p); Find(p);
}
int main(){
//srand(998244353);
int T = read(); LL n;
while (T--){
if (Miller_Rabin(n = read())) puts("Prime");
else {
pi = 0; Find(n);
//REP(i,pi) printf("%lld ",pr[i]); puts("");
if (pi == 1) {puts("Prime"); continue;}
LL x = pr[1];
for (int i = 2; i <= pi; i++)
x = min(x,pr[i]);
printf("%lld\n",x);
}
}
return 0;
}
Miiler-Robin素数测试与Pollard-Rho大数分解法的更多相关文章
- Miller-Rabin 素性测试 与 Pollard Rho 大整数分解
\(\\\) Miller-Rabin 素性测试 考虑如何检验一个数字是否为素数. 经典的试除法复杂度 \(O(\sqrt N)\) 适用于询问 \(N\le 10^{16}\) 的时候. 如果我们要 ...
- 数学--数论--随机算法--Pollard Rho 大数分解算法 (带输出版本)
RhoPollard Rho是一个著名的大数质因数分解算法,它的实现基于一个神奇的算法:MillerRabinMillerRabin素数测试. 操作流程 首先,我们先用MillerRabinMille ...
- Miller Rabin素数检测与Pollard Rho算法
一些前置知识可以看一下我的联赛前数学知识 如何判断一个数是否为质数 方法一:试除法 扫描\(2\sim \sqrt{n}\)之间的所有整数,依次检查它们能否整除\(n\),若都不能整除,则\(n\)是 ...
- POJ 2429 GCD & LCM Inverse(Miller-Rabbin素性测试,Pollard rho质因子分解)
x = lcm/gcd,假设答案为a,b,那么a*b = x且gcd(a,b) = 1,因为均值不等式所以当a越接近sqrt(x),a+b越小. x的范围是int64的,所以要用Pollard_rho ...
- 数学--数论--随机算法--Pollard Rho 大数分解算法(纯模板带输出)
ACM常用模板合集 #include <bits/stdc++.h> using namespace std; typedef long long ll; ll pr; ll pmod(l ...
- poj 1811 Prime Test 大数素数测试+大数因子分解
Prime Test Time Limit: 6000MS Memory Limit: 65536K Total Submissions: 27129 Accepted: 6713 Case ...
- poj1881:素因子分解+素数测试
很好的入门题 先测试是否为素数,若不是则进行素因子分解,算法详见总结贴 miller robin 和pollard rho算法 AC代码 #include <iostream> #incl ...
- 初学Pollard Rho算法
前言 \(Pollard\ Rho\)是一个著名的大数质因数分解算法,它的实现基于一个神奇的算法:\(MillerRabin\)素数测试(关于\(MillerRabin\),可以参考这篇博客:初学Mi ...
- 整数(质因子)分解(Pollard rho大整数分解)
整数分解,又称质因子分解.在数学中,整数分解问题是指:给出一个正整数,将其写成几个素数的乘积的形式. (每个合数都可以写成几个质数相乘的形式,这几个质数就都叫做这个合数的质因数.) .试除法(适用于范 ...
随机推荐
- React Native移动开发实战-2-如何调试React Native项目
在实际开发中,还有一个影响开发效率的重要因素:调试. 在1.4.3节中已经介绍了Enable Live Debugger的使用.本节来介绍另一个非常重要的调试选项:Debug JSRemotely选项 ...
- 01-numpy基础简介
import numpy as np # ndarray ''' # 三种创建方式 1.从python的基础数据对象转化 2.通过numpy内置的函数生成 3.从硬盘(文件)读取数据 ''' # 创建 ...
- type命令详解
转自:http://codingstandards.iteye.com/blog/831504 在脚本中type可用于检查命令或函数是否存在,存在返回0,表示成功:不存在返回正值,表示不成功. $ t ...
- php 常用英语小汇
bstract抽象的 -挨伯丝拽克特 access存取.访问 -挨克色丝 account账户 -厄靠恩特 action动作 -爱克身 activate激活 -爱克特维特 active活动的 -爱克得 ...
- React.js - 入门
React.js - 第1天 1. React简介 React 起源于 Facebook 的内部项目,因为该公司对市场上所有 JavaScript MVC 框架,都不满意,就决定自己写一套,用来架设 ...
- C++ 类 构造函数 constructor
构造函数 当定义了一个整型变量: int a; 这会申请了一块内存空间来存储a,但是这块内存中原本有数据的,可能是任何值,这不是你所希望的,若你就希望a表示1,所以要把a的值赋值为1. ; 例: #i ...
- 第10章 系统级I/O(下)
10.7 I/O重定向 Unix外壳提供了I/O重定向操作符,允许用户将磁盘文件和标准输出输入联系起来. 例如:unix>ls>foo.txt,使得外壳加载和执行ls程序,将标准输出重定 ...
- 奔跑吧DKY——团队Scrum冲刺阶段-Day 4
今日完成任务 谭鑫:主要解决之前存在的控件不灵敏问题,导致界面跳转不顺利. 黄宇塘:制作新的游戏背景图,对主界面图进行调整. 赵晓海:主要解决之前存在的控件不灵敏问题,导致界面跳转不顺利. 方艺雯:制 ...
- Java 面试 --- 3
上一篇,我们给出了大概35个题目,都是基础知识,有童鞋反映题目过时了,其实不然,这些是基础中的基础,但是也是必不可少的,面试题目中还是有一些基础题目的,我们本着先易后难的原则,逐渐给出不同级别的题目, ...
- Web应用程序的基本安全实践
创建安全Web应用程序的主题非常广泛.它需要研究以了解安全漏洞.您还需要熟悉Windows..NET框架和ASP.NET的安全设施.最后,有必要了解如何使用这些安全特性来对付威胁. 即使您没有安全方面 ...