试除法:最简单的因数分解算法,从$ 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. JavaScript使用readAsDataURL读取图像文件

    JavaScript使用readAsDataURL读取图像文件 FileReader对象的readAsDataURL方法可以将读取到的文件编码成Data URL.Data URL是一项特殊的技术,可以 ...

  2. PB中的DataStore的应用示例

    编程过程中想在窗口中加一个下拉列表(DDLB),原来听同学说过可以动态改变下拉列表的值,数据库中的表改变,前台客户端的下拉列表就会变,记得当时同学说的是用一个叫下拉数据窗口(DDDW)的东西做的,一直 ...

  3. js创建jsonArray传输至后台及后台解析

    //产品清单 //产品数量长度 var cnbvLength = FieldCount9 + 1; var arrayList=[]; for(var i = 0; i < cnbvLength ...

  4. java不同包中protected修饰的属性和方法调用方法

    protected修饰的静态属性和方法的调用方式1:直接类名调用 2:实例化父类对象进行调用 3:实例化子类对象进行调用 protected修饰的非静态属性和方法的调用方式:1:实例化子类对象进行调用 ...

  5. django 中实现文件下载的3种方式

    方法一:使用HttpResponse from django.shortcuts import HttpResponse def file_down(request): file=open('/hom ...

  6. 18 Python之初识面向对象

    1. 类与对象 class Car: #类名首字母大写,严格遵守驼峰命名规范 pass #造车 c = Car() #类名() #创建对象 ##出场之后进行改装 c.color = "红色& ...

  7. mysql5.5.x.zip 解压版安装教程

    一,前言 记一次安装解压版的mysql 5.5的经过,参考了一些文章,也遇到了一些错误,最终都安装成功了.在这里记录一下安装的过程,一方面自己做一个记录,领一方面给大家提供一份参考. 二,环境 1,w ...

  8. MongoDB系列(三):增删改查(CURD)

    上篇讲了MongoDB的基础知识,大家应该对MongoDB有所了解了,当然真正用的还是curd操作,本篇为大家讲解MongoDB的curd操作. 1.数据库操作 #.增 use config #如果数 ...

  9. MVC中 global.asax

    MVC框架下 global.asax 页面的事件 这些事件被触发的 顺序是: Application_BeginRequest Application_AuthenticateRequest Appl ...

  10. 百度网盘,FTP上传异常、上传失败的解决办法

    若你的宽带上传上限速度为50KB,那么将百度网盘或FTP的上行速度调为50KB以下即可,就不会出现网络异常的情况了.