分解质因数
Pollard-Rho 算法
模板:
const int prl[] = {2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37};
long long mul(long long a, long long b, long long M){return __int128(a) * b % M;}
long long gcd(long long a, long long b){return __gcd(a, b);}
long long add(long long a, long long b, long long M){a += b; while (a >= M)a -= M; return a;}
long long fpw(long long a, long long b, long long M){long long ret = 1;for (; b; b >>= 1, a = mul(a, a, M))if (b & 1)ret = mul(ret, a, M);return ret;}
bool check(int a, long long v){
long long d = v - 1, G = fpw(a, d, v);if (G != 1)return 1;
while ((d & 1) == 0){d >>= 1;if ((G = fpw(a, d, v)) == v - 1)return 0;else if (G != 1)return 1;}
return 0;
}
bool prm(long long v){
if (v <= 40){for (int a : prl)if (v == a)return 1;return 0;}
if (v < (1ll << 32)){if (check(2, v) || check(7, v) || check(61, v))return 0;return 1;}
for (int a : prl)if (check(a, v))return 0;return 1;
}
long long f(long long x, long long c, long long M){return add(mul(x, x, M), c, M);}
mt19937_64 rnd(time(nullptr));
long long PR(long long v){
long long c = rnd() % (v - 1) + 1;
long long t = f(0, c, v), r = f(f(0, c, v), c, v);
while (t != r){
long long d = gcd(abs(t - r), v);if (d > 1)return d;
t = f(t, c, v), r = f(f(r, c, v), c, v);
}
return v;
}
long long mxv;
void dfs(long long v){
if (v < mxv)return;
if (v < 100){
for (long long i = 2; i * i <= v; ++i)
if (v % i == 0){mxv = max(mxv, i);while (v % i == 0)v /= i;}
if (v != 1)mxv = max(mxv, v);
return;
}
long long d;while ((d = PR(v)) == v);if (prm(d))mxv = max(mxv, d); else dfs(d);
d = v / d;if (prm(d))mxv = max(mxv, d); else dfs(d);
}
long long get(long long v){mxv = 0; dfs(v); return mxv;}
void work(){
long long n, v;cin >> n;
if (prm(n))cout << "Prime" << endl;
else cout << get(n) << endl;//输出最小质因子
}
期望时间复杂度 \(O(n^{\frac 14})\)
参考
- \(\text{12.11 math1.pdf \; \;by Tx\_Lcy}\)

浙公网安备 33010602011771号