- 不会复杂度,正确性
- 核心思想 \(\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}})\)