Pollard_Rho
以下为分解最大质因子代码。
#include <ctime>
#include <iostream>
using i64 = long long;
#define DEBUG() std::cerr << __FUNCTION__ << " " << __LINE__ << std::endl
#define ctz __builtin_ctzll
i64 gcd(i64 a, i64 b);
i64 pow(i64 a, i64 k, i64 p);
i64 mul(i64 a, i64 b, i64 p);
int Miller_Rabin(i64 n);
void Pollard_Rho(i64 n);
int t;
i64 n, MaxFactor = 1;
int main() {
srand(time(0));
scanf("%d", &t);
while (t--)
scanf("%lld", &n), MaxFactor = 1, Pollard_Rho(n),
MaxFactor == n ? printf("Prime\n") : printf("%lld\n", MaxFactor);
return 0;
}
i64 gcd(i64 a, i64 b) {
// return b ? gcd(b, a % b) : a;
int shift = ctz(a | b);
b >>= ctz(b);
while (a) {
a >>= ctz(a);
if (a < b) std::swap(a, b);
a -= b;
}
return b << shift;
}
i64 pow(i64 a, i64 k, i64 p) {
i64 t = 1;
for (; k; a = mul(a, a, p), k >>= 1) if (k & 1) t = mul(t, a, p);
return t;
}
i64 mul(i64 a, i64 b, i64 p) {
i64 c = (a * b - (i64)((long double)a * b / p + 1e-9) * p) % p;
return c < 0 ? c + p : c;
}
int Miller_Rabin(i64 n) {
static const i64 P[] = { 2, 325, 9375, 28178, 450775, 9780504, 1795265022, 0 };
if (n < 2) return 0;
i64 m = n - 1, a, b; int k = 0;
while (!(m & 1)) m >>= 1, ++k;
for (int i = 0; P[i]; ++i) {
if (!(a = P[i] % n)) return 1;
a = b = pow(a, m, n);
for (int j = 1; j <= k; ++j, a = b)
if ((b = mul(a, a, n)) == 1 && a != 1 && a != n - 1) return 0;
if (a != 1) return 0;
}
return 1;
}
void Pollard_Rho(i64 n) {
if (n <= MaxFactor) return;
if (n == 1 || Miller_Rabin(n)) { MaxFactor = n; return; }
auto find = [](i64 n) {
static const int LIM = 1 << 22;
i64 x = rand() % n, y, z, w, c = rand() % (n - 1) + 1;
for (int i = 1; i <= LIM; i <<= 1) {
y = x, z = 1;
for (int j = 1; j <= i; ++j) {
x = (mul(x, x, n) + c) % n;
z = mul(z, std::abs(x - y), n);
if (j % 127 == 0 && (w = gcd(z, n)) > 1) return w;
}
if ((w = gcd(z, n)) > 1) return w;
}
return n;
};
i64 d;
for (d = n; d == n; d = find(n));
while (n % d == 0) n /= d;
Pollard_Rho(d), Pollard_Rho(n);
}