Pollard-Rho学习笔记

Pollard-Rho 还是很容易理解的,其作用就是找一个数 n 的一个非平凡约数。(非平凡约数即不是 1 也不是它本身的约数)。
复杂度大致是 n14logn

首先引入生日悖论:一年 365 天,当一个房间中的人数至少为 23 人时,两个人的生日日期相同的概率大于等于 50%
这个就让我们明白了在值域为 N 时,随机 O(N) 次就会出现一对相同的数。

于是我们设计一个伪随机数 f(x)=x2+c(modn)c 为随机的一个数。

为什么要这样做呢?我们设 n 最小的非平凡约数时 p,首先能发现一个很好的性质,若我们得到这个序列: x1,x2=f(x1),x3=f(x2),....,最终会形成一个循环节,也就像 ρ 一样。而且还满足:若 xy(modp)f(x)f(y)(modp)。由上文的生日悖论,可以得到出现 xixj(modp) 的期望复杂度是 O(p) 的,但我们并不知道 p 为多少,我们只知道当 xixj(modp) 时,gcd(|xixj|,n) 不为 1,而这也就是我们对重复了的情况的判断标准。(记住是不为 1,所以找到的约数可能是 n。)

然后我们相当于就是需要在较快的时间内判断环是否出现。

这里简单介绍一下 floyd 判环,因为这是主要思想,其他做法也只是这个做法的优化。我们把 xixj(modp) 当成两个人在环上跑,其中一个人超了另一个人一圈。所以我们使用两个指针,一个每次跳一步,另一个每次跳两步,然后每次做差判断是出现环。

至于优化,这里讲倍增优化,我们第 k 轮让后面那个指针跳 2k 步,前面指针不动,如果出现 gcd 不为 1 的情况,就说明出现了环。

我们考虑到如果每次都要判 gcd 就要带一个 log,也就是 O(plogn),而我们知道若 gcd(|xixj|,n) 不为 1,那 gcd(Π|xixj|modn,n) 也不为 1,所以我们考虑计算乘积与 ngcd,我们考虑每 k 次就算一次 gcd,那复杂度就变成了 O(plognk+p),这里 k 是一个常数,自己定义即可。

分解质因数还需要 Miller-Rabin 的辅助,Miller-Rabin 相对简单,故不再赘述。

分解质因数代码:

点击查看代码
#define ll __int128
#define int long long
struct Miller_Rabin{
int pri[13]={0,2,3,5,7,11,13,17,19,23,29,31,37},cnt=12;
inline bool chk(ll n,ll p){
if(n%p==0) return false;
ll num=n-1,t=0;
while(num%2==0) num/=2,t++;
ll v=qpow(p,num,n),s=0;
if(v==1) return true;
for(;s<t;s++){
if(v==n-1) return true;
v=v*v%n;
}
if(s==t) return false;
return true;
}
inline bool is_pri(int n){
for(int i=1;i<=cnt;i++){
if(pri[i]==n) return true;
if(!chk(n,pri[i])) return false;
}
return true;
}
}Test;
struct Pollard_Rho{
int k=127;
inline ll F(ll x,ll c,ll mod){
x%=mod;
return (x*x+c)%mod;
}
inline ll abs(ll x){return (x>0)?x:-x;}
inline int gt_div(ll x){
int c=rand()%(x-1)+1;
ll s=0,t=0,v=1;
ll tt=0;
for(int w=1;;w<<=1,s=t){
for(int num=1;num<=w;num++){
tt++;
t=F(t,c,x);
v=v*(abs(t-s)%x)%x;
if(!v) return x;
if(num%k==0){
int d=__gcd(v,x);
if(d>1) return d;
}
}
int d=__gcd(v,x);
if(d>1) return d;
}
}
}Pr;
inline void fac(int x){
if(x==1) return ;
if(Test.is_pri(x)){
cout<<x<<' ';
return ;
}
int now=x; while(now==x) now=Pr.gt_div(x);
x/=now;
fac(x); fac(now);
}
posted @   ~Cyan~  阅读(10)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
点击右上角即可分享
微信分享提示