Pollard Rho

Miller Rabin

PON - Prime or Not

  • 若 $p$ 为素数,那么 $\forall p \nmid a, a^{p-1} \equiv 1 (\mod p)$。

  • 若 $p$ 为奇素数,那么 $x^2 \equiv 1(\mod p)$ 的解为 $x \equiv \pm 1(\mod p)$。

取前 $12$ 个素数($2,3,5,7,11,13,17,19,23,29,31,37$)就够用了。OEIS

时间复杂度 $O(\log V)$。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
inline int qm(int x,int y,int p){ int res=1; for(;y;y>>=1,x=(i128)x*x%p) if(y&1) res=(i128)res*x%p; return res; }
int pr[15]={0,2,3,5,7,11,13,17,19,23,29,31,37};
int chk(int x,int p){
int d=p-1,cur; for(;!(d&1);d>>=1);
cur=qm(x,d,p); if(cur==1) return 1;
for(;d<=p-1;d<<=1){
if(cur==p-1) return 1;
cur=(i128)cur*cur%p;
}
return 0;
}
int chk(int p){
if(p>37){ for(int i=1;i<=12;++i) if(!chk(pr[i],p)) return 0; return 1; }
else{ for(int i=1;i<=12;++i) if(pr[i]==p) return 1; return 0; }
}

Pollard Rho

【模板】Pollard-Rho

构造函数 $f(x)=x^2+c$,记 $x_0=0,x_i=f(x_{i-1})$。

每次找 $\gcd(\Delta x,p)$ 是很优的。

$x_i$ 会形成类似 $\rho$ 的图形,由生日悖论可知其长度期望为 $O(\sqrt[4]{p})$,考虑枚举 $i$,当 $x_{2i}=x_i$ 时退出,这样来判环。

期望时间复杂度 $O(\sqrt[4]{n}\log n)$。

根据 $\gcd(a,n) \mid \gcd(ab \mod n,n)$,将 $\Delta x$ 乘起来,达到一定限度是求 $\gcd$ 判断。

对限度倍增,与 $128$ 取 $\min$ 较优。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#define get(l,r) (rnd()%((r)-(l)+1)+(l))
mt19937_64 rnd(time(0));
inline int qm(int x,int y,int p){ int res=1; for(;y;y>>=1,x=(i128)x*x%p) if(y&1) res=(i128)res*x%p; return res; }
int div(int p){
int c=get(1,p-1),s=c,t=0,prod=1,lim=1,cnt=0,d;
auto f=[&](int x){ return ((i128)x*x+c)%p; };
for(;s!=t;s=f(f(s)),t=f(t)){
prod=(i128)prod*abs(s-t)%p;
if(++cnt==lim){
if((d=__gcd(prod,p))!=1) return d;
cnt=0,lim=min(lim<<1,B);
}
}
if((d=__gcd(prod,p))!=1) return d; return p;
}
int find(int p){
if(p==1) return 1;
if(chk(p)) return p;
int d=div(p); for(;d==p;d=div(p));
for(;p%d==0;p/=d);
return max(find(d),find(p));
}

参考

Pollard Rho

初等数论学习笔记 II:分解质因数