Pollard-Rho
- 不会复杂度,正确性
- 核心思想 \(\rightarrow\) 生日悖论
Miller-Rabin素性测试
分为两步,判断 \(p\) 是否是素数
1, 取一个底数 \(a\) ,\(2^{31}\) 以内取 \(\{ 2,7,61 \}\) 三个即可
2,设 \(2^tu=p-1\),依次判断 \(a^{2^ku}(0\le k\le t)\) 是否等于 \(1\),如果是,那么通过当前测试
bool P(ll n) {
if(n < 3 || !(n & 1)) return n == 2;
if(n % 3 == 0) return n == 3;
ll u = n - 1, t = 0, tst = 6;
while(!(u & 1)) u /= 2, ++t;
while(tst--) {
ll a = rd() % (n - 3) + 2, v = qp(a, u, n);
if(v == 1) continue;
int s;
for(s = 0; s < t; s++) {
if(v == n - 1) break;
v = (i2) v * v % n;
}
if(s == t) return 0;
}
return 1;
}
Pollard-Rho
每次随机取出两个数,判断 \(gcd(abs(x-y),n)\) 是否大于 \(1\)
随机取基于一个函数 \(f(x)=x^2+c\) 采用龟兔赛跑制,每次 \(x\) 变化一次,\(y\) 变化两次,即 \(x=f(x) \ \ \ \ y = f(f(y))\)
ll f(ll x, ll c, ll n) {return ((i2) x * x + c) % n;}
inline ll A(ll x) {return x > 0 ? x : -x;}
ll pr(ll n) {
if(n == 4) return 2;//奇妙特判?构造的函数有问题
ll c = rd() % (n - 1) + 1;
ll t = f(0, c, n), r = f(t, c, n);
while(t != r) {
ll d = __gcd(A(t - r), n);
if(d > 1) return d;
t = f(t, c, n), r = f(f(r, c, n), c, n);
}
return n;
}
void fac(ll x) {
if(x <= mp || x < 2) return;
if(P(x)) {mp = x; return;}
ll p = x;
while(p >= x) p = pr(x);
while(!(x % p)) x /= p;
fac(x), fac(p);
}
时间复杂度是 \(O(n^{\frac{1}{4}})\)