Pollard-rho算法[因子分解算法]
试除法:最简单的因数分解算法,从$ 2 $到$ \sqrt n $一个一个试。
试除法(改进):从$ 2 $到$ \sqrt n $挑素数一个一个试。
然而这样复杂度是相当高的。
生日悖论:指如果一个房间里有23个或23个以上的人,那么至少有两个人的生日相同的概率要大于50%。
我们在$ [2,n) $取一个数,该数是$ n $的因子的概率很小.
我们取$ k $ 个数$ x_1,x_2,x_3...x_k $,而取出的 $ k $ 个数中,$ \exists i,j : (x_i-x_j) | n $ 的概率随着$ k $ 增大而增高。
我们有一个更好的办法:
对选取的$ k $ 个数 $ x_1,x_2,x_3...x_k $,不再询问是否存在$ (x_i-x_j) | n $,改为询问 $ gcd(x_i-x_j,n)>1 $ 的情况。
所以,一个简单的策略如下:
1.在区间$[2,n)$ 中随即选取$ k $个数$ x_1,x_2,x_3...x_k $
2.判断是否存在$ gcd(x_i-x_j,n)>1 $ , 若存在,$ gcd(x_i-x_j,n)>1 $ 是$ n $的一个因子。
我们大概需要选取$ n^{\frac{1}{4}}$个数,这可能存不下。
Pollard's Rho 算法
为了解决数太多无法储存的问题,Pollard's Rho 算法之将两个数存在内存里,我们生成并检查这两个数,反复执行这个步骤并希望得到我们想要的数。
我们不断使用一个函数来生成这个序列(有点像随机数),并非所有函数都可以,但有一个神奇的函数可以$ f(x)=(x^2+a)mod n $; $ a $ 可以指定也可以随机。
这个序列显然是存在环的,如何检测环出现呢?
方法一:floyd判环法
floyd判环法:假如两个人$A、B$在环上走,如何知道已经走完一圈呢? 让$B$以$A$两倍的速度走,$B$第一次赶上$A$时,$B$至少走完一圈了
设定$ x=y=x0 $的初始值,进行迭代,每次:$ x=f(x), y=f(f(y)) $ 即:$ x=x_i,y=x_{2i} $
若$ gcd(x−y,n)=1 $,那么继续枚举下一对 $x,y$ 。
若$ gcd(x−y,n)=n $,更换随机函数 f(x)f(x) ,重新进行算法。
否者我们就找到了一个n的非平凡因子 $ d=gcd(x-y,n) $
当 $x==y$时出现循环,此时$x-y=0$,$ gcd(x−y,n)=n $,即为2情况。
LL pollardRho(LL n, int a){
LL x=,y=,d=;
while(d==){
x=(x*x+a)%n;
y=(y*y+a)%n;y=(y*y+a)%n;
d=gcd(abs(x-y),n);
}
if(d==n) return pollardRho(n,a+);
return d;
}
方法二:brent判环法
不同于floyd每次计算$x_i,x_{2i}$进行判断,brent每次只计算$x_i$,当$k$是2的方幂时,$y=x_k$,每次计算$d=gcd(x_k−y,n)$
LL pollardRho(LL n, int a){
LL x=,y=,d=,k=,i=;
while(d==){
++k;
x=(x*x+a)%n;
d=gcd(abs(x-y),n);
if(k==i){y=x;i<<=;}
}
if(d==n)return pollardRho(n,a+);
return d;
}
求全部因子(结合miller-rabin测试)
LL cnt,fact[];
LL gcd(LL a,LL b){return !b?a:gcd(b,a%b);}
LL pollardRho(LL n, int a){
LL x=rand()%n,y=x,d=,k=,i=;
while(d==){
++k;
x=ksc(x,x,n)+a;if(x>=n)x-=n;
d=gcd(x>y?x-y:y-x,n);
if(k==i){y=x;i<<=;}
}
if(d==n)return pollardRho(n,a+);
return d;
}
void findfac(LL n){
if(millerRabin(n)){fact[++cnt]=n;return;}
LL p=pollardRho(n,rand()%(n-)+);
findfac(p);
findfac(n/p);
}
例题:POJ1811
https://files-cdn.cnblogs.com/files/Doggu/Pollard-rho%E7%AE%97%E6%B3%95%E8%AF%A6%E8%A7%A3.pdf
https://blog.csdn.net/qq_39972971/article/details/82346390
https://www.cnblogs.com/book-book/p/6349362.html
Pollard-rho算法[因子分解算法]的更多相关文章
- Pollard Rho算法浅谈
Pollard Rho介绍 Pollard Rho算法是Pollard[1]在1975年[2]发明的一种将大整数因数分解的算法 其中Pollard来源于发明者Pollard的姓,Rho则来自内部伪随机 ...
- Pollard rho算法+Miller Rabin算法 BZOJ 3668 Rabin-Miller算法
BZOJ 3667: Rabin-Miller算法 Time Limit: 60 Sec Memory Limit: 512 MBSubmit: 1044 Solved: 322[Submit][ ...
- 初学Pollard Rho算法
前言 \(Pollard\ Rho\)是一个著名的大数质因数分解算法,它的实现基于一个神奇的算法:\(MillerRabin\)素数测试(关于\(MillerRabin\),可以参考这篇博客:初学Mi ...
- Pollard Rho 算法简介
\(\text{update 2019.8.18}\) 由于本人将大部分精力花在了cnblogs上,而不是洛谷博客,评论区提出的一些问题直到今天才解决. 下面给出的Pollard Rho函数已给出散点 ...
- Miller Rabin素数检测与Pollard Rho算法
一些前置知识可以看一下我的联赛前数学知识 如何判断一个数是否为质数 方法一:试除法 扫描\(2\sim \sqrt{n}\)之间的所有整数,依次检查它们能否整除\(n\),若都不能整除,则\(n\)是 ...
- 大整数分解质因数(Pollard rho算法)
#include <iostream> #include <cstring> #include <cstdlib> #include <stdio.h> ...
- BZOJ 5330 Luogu P4607 [SDOI2018]反回文串 (莫比乌斯反演、Pollard Rho算法)
题目链接 (BZOJ) https://www.lydsy.com/JudgeOnline/problem.php?id=5330 (Luogu) https://www.luogu.org/prob ...
- Pollard Rho因子分解算法
有一类问题,要求我们将一个正整数x,分解为两个非平凡因子(平凡因子为1与x)的乘积x=ab. 显然我们需要先检测x是否为素数(如果是素数将无解),可以使用Miller-Rabin算法来进行测试. Po ...
- 【快速因数分解】Pollard's Rho 算法
Pollard-Rho 是一个很神奇的算法,用于在 $O(n^{\frac{1}4}) $的期望时间复杂度内计算合数 n 的某个非平凡因子(除了1和它本身以外能整除它的数).事书上给出的复杂度是 \( ...
随机推荐
- 多边形面积(Area_Of_Polygons)
原理: 任意多边形的面积可由任意一点与多边形上依次两点连线构成的三角形矢量面积求和得出. 分析: 由于给出的点是相对于我们的坐标原点的坐标,每个点实际上我们可以当作一个顶点相对于原点的向量,如下图所示 ...
- 稀疏矩阵三元组快速转置(转poklau123写的很清楚)
关于稀疏矩阵的快速转置法,首先得明白其是通过对三元表进行转置.如果误以为是对矩阵进行转置,毫无疑问就算你想破脑袋也想不出个所以然,别陷入死胡同了! 对于一个三元表,行为i,列为j,值为v.需将其i与j ...
- 关于Android studio调用高德地图的简单流程和要点
一,账号与Key的申请 注册成为高德开发者需要分三步: 第一步,注册高德开发者:第二步,去控制台创建应用:第三步,获取Key. 前2步都比较简单,这里说下第三步. 获取Key 1.进入控制台,创建一个 ...
- luogu题解 P1707 【刷题比赛】矩阵加速递推
题目链接: https://www.luogu.org/problemnew/show/P1707 分析: 洛谷的一道原创题,对于练习矩阵加速递推非常不错. 首先我们看一下递推式: \(a[k+2]= ...
- log4j2配置文件xml详细了解
log4j2配置文件xml详细了解 详细参考:https://www.cnblogs.com/new-life/p/9246143.html log4j 2.x版本不再支持像1.x中的.propert ...
- springboot(十九)-线程池的使用
我们常用ThreadPoolExecutor提供的线程池服务,springboot框架提供了@Async注解,帮助我们更方便的将业务逻辑提交到线程池中异步执行. 话不多说,编码开始: 1.创建spri ...
- 【异常】org.apache.hadoop.hdfs.server.common.InconsistentFSStateException
1 异常信息 - ::, INFO org.apache.hadoop.hdfs.server.namenode.FSNamesystem: Maximum size of an xattr: -- ...
- deep_learning_tensorflow_get_variable()
maxwell_tesla tf.get_variable函数的使用 tf.get_variable(name, shape, initializer): name就是变量的名称,shape是变量的 ...
- 逆天!百度AI音箱重磅升级:最大梦想实现
7月3日-7月4日,“Baidu Create 2019”百度AI开发者大会,在中国北京·国家会议中心举行. 百度创始人.董事长兼首席执行官李彦宏将与百度各业务板块的领军人物一起,为来自全球各地的开发 ...
- Chrome OS 更新新版本可让Linux访问USB连接的Android设备
谷歌再次为Chrome OS带来了重大版本更新,使版本号达到了75.本次更新的一大亮点就是允许在Chrome OS上运行的Linux能够识别通过USB方式连接的Android设备,能够让用户使用Lin ...