试除法:最简单的因数分解算法,从$ 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. laravel 5.7 引入Illuminate\Http\Request 在类内调用 Request 提示不存在的问题

    laravel报错: ReflectionException Class App\Http\Controllers\Request does not exist 解决办法: namespace App ...

  2. Shell随机生成字符串

    随机生成18位的字符串,数字 大小写字符 斜线 password=`openssl rand -base64 |-`

  3. python之jupyter安装与使用

    Jupyter Notebook 的本质是一个 Web 应用程序,便于创建和共享文学化程序文档,支持实时代码,数学方程,可视化和 markdown.用途包括:数据清理和转换,数值模拟,统计建模,机器学 ...

  4. css样式水平居中和垂直居中的方法

    水平居中(包含块中居中) 1. 定宽,左右margin为auto.(常规流块盒.弹性项目[不用定宽]) 例子:在box1盒子上设置宽,再设置margin:auto: <style> .bo ...

  5. vue-cli常用配置

    官方配置表:https://cli.vuejs.org/zh/config/#publicpath 1.vue inspect > output.js 将配置按webpack.config.js ...

  6. Spark 2.43读取.json文件入库到MySQL 8

    如果没有安装包,可以用我的这个 百度网盘链接点击进入 提取码: eku1 解压之后 准备开始配置环境变量 如果运行时候报错参考 (java.io.IOException: Could not loca ...

  7. ldap搭建

    yum install openldap openldap-servers openldap-clients -y #检查是否安装成功 slapd -VVopenldap的配置文件都在/etc/ope ...

  8. IO模型(epoll)--详解-03

    写在前面 epoll是开发linux高性能服务器的必备技术至,epoll本质,是服务端程序员的必须掌握的知识. 七.epoll的原理和流程 本节会以示例和图表来讲解epoll的原理和流程. 创建epo ...

  9. AIX 下的 find 命令使用

      平常我们使用 find , -size +100M/K/G ,就可以找到相应大小的文件了. 可是 AIX 平台下,却好像不能使用,虽然执行起来不报错,但是查找出来的文件却并不是我们想要的.所以 m ...

  10. 牛客第八场 C-counting paths 树形dp计数

    题目地址 题意 给你一颗树 初始点颜色全部为白色 对于每一个满足要求一的点集s f(s)的定义为先把点集内的点染黑 满足要求二的路径集合数量 要求一为两两黑点之间不能出现白色的点 要求二为将这个路径集 ...