写在前面

目录

问题的提出

生日悖论

利用生日悖论来因数分解

Pollard-rho算法

例题完成进度

1/2


问题的提出

如何快速地找到一个自然数N的两个因数(除自己和1以外)?

首先想到的肯定是传统的试除法

int main(){
int N;
cin>>N;
if(N%==){
cout<<<<" "<<N/<<endl;
return ;
}
for(int i=;i<=sqrt(N);i+=){
//这里是一个优化了的试除法,可以直接排除偶数
if(N%i==){
cout<<i<<" "<<N/i<<endl;
return ;
}
}
cout<<"No!"<<endl;
return ;
}

这里还有一个比较不走心的算法叫I am feeling lucky algorithm

这种算法的思想就是随机生成一个[2,N]的数,若恰好生成了N的因数,那么就输出,否则就停止.

那么这种算法成功(也就是恰好生成N的因数)的概率是多少呢?

我们来试想一下最坏的情况,就是在[2,N-1]的范围内,N恰好只有两个因数。

那么我们正好找到这两个因数其中之一的概率就是$\frac{2}{N-1}$。

如果N比较大,约为1010时,成功的概率约为$\frac{1}{5000000000}$,这比彩票中奖的概率还要小QAQ

这样当然是不行的,如果要确保找到一个因数,那么我们需要用不同的随机数判断将近N次,这样会比试除法还要暴力。

不过,虽然这个算法显然是不行的,但是它给我们提供了一个思路——随机

go back


生日悖论

如果你要从[1,1000]中随机取一个数,那么显然取得一个指定的数(假设为51)的概率为$\frac{1}{1000}$

把这个问题修改一下,如果我要从这1000个数中任意取两个数,使得这两个数的差的绝对值为51的概率又是多少呢?

因为会取绝对值,所以我们可以完全随机选择第一个数,也就是说,选择第一个数符合条件的概率是100%

又根据对称性可知,选中第二个数符合条件的情况有两种,概率为$\frac{2}{999}$

于是最后的总概率就约为$\frac{1}{500}$

如果我们再修改一下这个问题,从1000个数中任选出k=3,4,5……个数,那么可以发现,成功的概率是单调递增的

我们再来看看到底什么是生日悖论

就是随机选取一名学生,他的生日恰好为6月1日的概率为$\frac{1}{365}$

那么这相当于我们在[1,365]中选取任意一个数为指定的数的概率为多少,于是就变成了上面的问题。

同样的如果我们要求任意选k=2,3,4……个学生,其中有人生日在同一天的概率为多少?

显然这个概率也是递增的,当k>50时,概率已经约等于100%了。也就是说,假定一个班有50多个人,在随机分班的情况下,应该几乎是一定会有两个人生日在同一天。

然而事实上似乎并没有那么高的概率,所以这个问题被称为生日悖论

go back


利用生日悖论来因数分解

让我们再回头看看前面提到的I am feeling lucky algorithm,已知我们随机地从[2,N-1]中选择出一个数是N的因数的概率是极小的,这也就意味着需要重复随机选择来提高正确率。

那么如果我们不是只选择一个数,而是选择k个数,保证其中两个数的差值是N的因数。

而如果其中两个数x,y的差值为N的因数,就一定会有gcd(|x-y|,N)>1

假设N只有两个因数(除去自己和1)p和q的情况下,那么就意味着此时只有这两个数能整除N

但是如果我们要求的是有多少个数x保证gcd(x,N)>1,此时答案就很多了,有p+q-2个

于是我们就得出了一个简单的策略:

1.在区间[2,N-1]中随机选取k个数,x1~k

2.判断是否存在gcd(xi-xj,N)>1,若存在,则显然gcd(xi-xj,N)是N的一个因数

同时也出现了一个问题,就是我们需要选取大约$N_{}^{\frac{1}{4}}$个数,内存显然是不可能够的

那么又要如何解决这个问题呢?于是Pollard-rho算法就出现了。

go back


Pollard-rho算法

因为数字太多内存不够,所以Pollard-rho只把连续的两个数存在内存中。

也就是说,我们并不会选出k个数,而是一个一个地生成伪随机数,并检查连续的两个数是否符合条件。

我们会用一个函数来生成伪随机数,就是这个→f(x)=(x2+a)%N

其中的a可以自己指定或rand()生成

这样看起来484很棒?但是这样也伴随了一个问题就是这个函数生成的伪随机数还是有规律的,会无限循环。

于是就会出现像希腊字母$\rho$一样的情况,这也是为什么这个算法名字中含有rho

那么我们又要如何避免这种情况呢?

首先为了保证没有答案可能被遗漏,那么至少要把这个环完整的扫一遍。

联想一下一个比较常见的问题,就是小学数学题做过的两个人在环形操场上跑步,在同时起跑的情况下,当速度快的那个人追上速度慢的那个人的时候,一定已经多跑了一圈,也就是说此时两人肯定都至少跑完了一圈,恰好符合我们的要求。

那么就是说我们要用两个变量来存储,一个用v的速度扫描环,一个用2v的速度,如果当两个变量相等时还没有找到答案,就退出这个环,重新取随机数,再次带入上面提到的函数中。

这里有一点要说明一下,就是为什么快的速度一定要是慢的速度的两倍而不能更大。

假设快的速度为kv(k>2),整个环的路程为s,快的追上慢的所需时间为t,那么我们可以列出式子:

$kvt-vt=s\Rightarrow(k-1)vt=s\Rightarrow vt=\frac{s}{k-1}$

因为k>2,所以k-1>1,那么就有$\frac{s}{k-1}<s$,也就意味着此时用来判断答案是否符合条件的(也就是速度较慢的那个)还没有扫描完整个环,那么就有可能会有答案被遗漏。

以上就是完整的Pollard-rho算法过程,接下来上代码

void Pollard_rho(long long N){
long long a=rand()%N+;//随机生成常数a
long long x1,x2,d;
x1=x2=rand()%N+;
while(){
x1=count(x1,cc);x2=count(count(x2,cc),cc);
if(x1==x2) {x1=x2=rand()%N+;cc=rand()%N+;}
d=gcd(abs(x2-x1),N);
if(d>&&d<N){p=d;q=N/p;return;}//p,q记录N的因数
}
return;
}

go back


例题

Luogu P4358 密钥破解

Luogu P4718 Pollard-rho模板

go back

Pollard-rho算法学习笔记的更多相关文章

  1. C / C++算法学习笔记(8)-SHELL排序

    原始地址:C / C++算法学习笔记(8)-SHELL排序 基本思想 先取一个小于n的整数d1作为第一个增量(gap),把文件的全部记录分成d1个组.所有距离为dl的倍数的记录放在同一个组中.先在各组 ...

  2. Manacher算法学习笔记 | LeetCode#5

    Manacher算法学习笔记 DECLARATION 引用来源:https://www.cnblogs.com/grandyang/p/4475985.html CONTENT 用途:寻找一个字符串的 ...

  3. Pollard rho算法+Miller Rabin算法 BZOJ 3668 Rabin-Miller算法

    BZOJ 3667: Rabin-Miller算法 Time Limit: 60 Sec  Memory Limit: 512 MBSubmit: 1044  Solved: 322[Submit][ ...

  4. 初学Pollard Rho算法

    前言 \(Pollard\ Rho\)是一个著名的大数质因数分解算法,它的实现基于一个神奇的算法:\(MillerRabin\)素数测试(关于\(MillerRabin\),可以参考这篇博客:初学Mi ...

  5. Pollard Rho 算法简介

    \(\text{update 2019.8.18}\) 由于本人将大部分精力花在了cnblogs上,而不是洛谷博客,评论区提出的一些问题直到今天才解决. 下面给出的Pollard Rho函数已给出散点 ...

  6. Johnson算法学习笔记

    \(Johnson\)算法学习笔记. 在最短路的学习中,我们曾学习了三种最短路的算法,\(Bellman-Ford\)算法及其队列优化\(SPFA\)算法,\(Dijkstra\)算法.这些算法可以快 ...

  7. Pollard Rho算法浅谈

    Pollard Rho介绍 Pollard Rho算法是Pollard[1]在1975年[2]发明的一种将大整数因数分解的算法 其中Pollard来源于发明者Pollard的姓,Rho则来自内部伪随机 ...

  8. 某科学的PID算法学习笔记

    最近,在某社团的要求下,自学了PID算法.学完后,深切地感受到PID算法之强大.PID算法应用广泛,比如加热器.平衡车.无人机等等,是自动控制理论中比较容易理解但十分重要的算法. 下面是博主学习过程中 ...

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

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

  10. Johnson 全源最短路径算法学习笔记

    Johnson 全源最短路径算法学习笔记 如果你希望得到带互动的极简文字体验,请点这里 我们来学习johnson Johnson 算法是一种在边加权有向图中找到所有顶点对之间最短路径的方法.它允许一些 ...

随机推荐

  1. 一个简易的kmp教学并给出java实现

    简单介绍一下问题 给定source字符串,找出target字符串出现的首位 例如 source   为“abddabddabc” target 为 “abddabc” 从第一位开始比较 |a b d ...

  2. Raneto部署知识库平台&支持中文搜索

    目录 环境 更新软件包 部署 Raneto 知识库平台 安装 Node 环境 安装 node 管理工具 查看 node 列表 安装需要的Node版本 使用 淘宝NPM源 git 使用代理设置,大陆地区 ...

  3. python 提取pdf文字

    安装pdfminer 库 windows 下安装pdfminer3k pip install pdfminer3k Liunx 下安装pdfminer pip install pdfminer 代码 ...

  4. Activiti开发案例之代码生成工作流图片

    图例 环境 软件 版本 SpringBoot 1.5.10 activiti-spring-boot-starter-basic 6.0 生成代码 以下是简化代码: /** * 查看实例流程图,根据流 ...

  5. Python--day13(函数嵌套定义,global、nonlocal、闭包函数、装饰器)

    今日主要内容 1.  函数的嵌套定义 2.  global.nonlocal关键字 3.  闭包及闭包的应用场景 4. 装饰器 1.  函数的嵌套定义 概念:在一个函数的内部定义另一个函数 为什么要有 ...

  6. ABP之模块系统

    简介 ASP.NET Boilerplate提供了构建模块的基础结构,并将它们组合在一起以创建应用程序. 模块可以依赖于另一个模块. 通常,一个程序集被视为一个模块. 如果创建具有多个程序集的应用程序 ...

  7. mysql jdbc 官方编程示例

    /* Basic example of an application using JDBC API of Connector/C++ */ /* Standard C++ includes */ #i ...

  8. win 解压安装mysql步骤

    5  安装成功之后,启动mysql时报错: 系统错误2,找不到指定的文件.原因:有的系统安装过MySQL没有卸载干净,或者系统自带精简版的MySQL导致注册表关于MySQL的配置与实际安装路径不一致. ...

  9. vue各种插件汇总

    https://blog.csdn.net/wh8_2011/article/details/80497620(copy) Vue是什么? Vue.js(读音 /vjuː/, 类似于 view) 是一 ...

  10. 【JMeter】(1)---入门

    JMeter入门 https://www.cnblogs.com/qdhxhz/p/9222105.html 一.概述 JMeter是Apache下一款在国外非常流行和受欢迎的开源性能测试工具,JMe ...