试除法:最简单的因数分解算法,从$ 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算法[因子分解算法]的更多相关文章

  1. Pollard Rho算法浅谈

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

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

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

  3. 初学Pollard Rho算法

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

  4. Pollard Rho 算法简介

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

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

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

  6. 大整数分解质因数(Pollard rho算法)

    #include <iostream> #include <cstring> #include <cstdlib> #include <stdio.h> ...

  7. BZOJ 5330 Luogu P4607 [SDOI2018]反回文串 (莫比乌斯反演、Pollard Rho算法)

    题目链接 (BZOJ) https://www.lydsy.com/JudgeOnline/problem.php?id=5330 (Luogu) https://www.luogu.org/prob ...

  8. Pollard Rho因子分解算法

    有一类问题,要求我们将一个正整数x,分解为两个非平凡因子(平凡因子为1与x)的乘积x=ab. 显然我们需要先检测x是否为素数(如果是素数将无解),可以使用Miller-Rabin算法来进行测试. Po ...

  9. 【快速因数分解】Pollard's Rho 算法

    Pollard-Rho 是一个很神奇的算法,用于在 $O(n^{\frac{1}4}) $的期望时间复杂度内计算合数 n 的某个非平凡因子(除了1和它本身以外能整除它的数).事书上给出的复杂度是 \( ...

随机推荐

  1. 从入门到自闭之Python自定义模块

    自定义模块 定义:一个文件就是一个模块(能被调用的文件,模块就是一个工具箱,工具就是函数) 作用: 将代码文家化管理,提高可读性,避免重复代码 拿来就用(避免重复造轮子),python中类库比较多,提 ...

  2. 设置队列中文件上的“X”号的点击事件+uploadLimit动态加1

    目的:1.设置文件队列中“x”号的点击事件 2.每次删除服务器文件后,把uploadLimit + 1: 'onUploadSuccess': function (file, data, respon ...

  3. 第二章 单表查询 T-SQL语言基础(2)

    单表查询(2) 2.2 谓词和运算符 T-SQL有几种不同的语言元素可以指定逻辑表达式,例如,查询过滤器(WHERE和HAVING),CHECK约束,等等. 在逻辑表达式中可以使用各种谓词(取值为TR ...

  4. JQuery——关于CDN(内容分发网络)

    替代方案 如果您不希望下载并存放 jQuery,那么也可以通过 CDN(内容分发网络) 引用它. Staticfile CDN.百度.又拍云.新浪.谷歌和微软的服务器都存有 jQuery . 如果你的 ...

  5. angular使用@angular/material 出现"export 'ɵɵinject' was not found in '@angular/core'

    WARNING in ./node_modules/@angular/cdk/esm5/a11y.es5.js 2324:206-214 "export 'ɵɵinject' was not ...

  6. 自定义zabbix中的普通KEY及LLD KEY

    普通类型KEY 1.agent端: 编写自定义脚本,脚本需要有输出值返回给zabbix-server,并且给对应脚本赋予zabbix用户可执行权限 zabbix-agnet 且定义key名称和comm ...

  7. PHP7安装redis扩展

    PHP7安装redis扩展优秀开源项目:http://github.crmeb.net/u/liaofeiyum -y install git git clone https://github.com ...

  8. 安装vim自动补全插件

    1 安装VIM 2 安装vim插件管理工具.过程见链接.(谢谢) 3 在.vimrc中添加下列代码 Bundle 'Valloric/YouCompleteMe' 保存退出后打开vim,在正常模式下输 ...

  9. 第二章 Vue快速入门-- 24 过滤器-Vue中全局过滤器的基本使用

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8&quo ...

  10. 关于ORACLE的串行化隔离级别--来自ORACLE概念手册

    为了描述同时执行的多个事务如何实现数据一致性,数据库研究人员定义了被 称为串行化处理(serializability)的事务隔离模型(transaction  isolation model).当所有 ...