Pollard Rho
从未如此美妙的开局,请为我欢呼,为我喝彩,ok?
快速乘使用黑科技,取前\(12\)个质数可以保证正确性,注意Pollard
中t++ % 40
不要打错。
#include <cstdio>
#include <iostream>
#include <vector>
#include <algorithm>
#define vi vector<ull>
using namespace std;
template <typename T>
inline void read(T &x) {
x = 0; int f = 0; char ch = getchar();
for(; !isdigit(ch); ch = getchar()) if(ch == '-') f = 1;
for(; isdigit(ch); ch = getchar()) x = (x << 3) + (x << 1) + (ch ^ 48);
if(f) x = ~x + 1;
}
using LL = long long;
using ull = unsigned long long;
ull mul(ull x, ull y, ull P) {
LL res = x * y - P * ull(1.L / P * x * y);
return res + P * (res < 0) - P * (res >= (LL)P);
}
ull fpow(ull x, ull pnt, ull P) {
if(x >= P) x %= P;
ull res = 1;
for(; pnt; pnt >>= 1, x = mul(x, x, P))
if(pnt & 1) res = mul(res, x, P);
return res;
}
const ull A[] = {2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37};
bool isPrime(ull n) {
if(n < 3 || !(n & 1)) return n == 2;
ull s = __builtin_ctz(n - 1), t = n >> s;
for(ull a : A) {
ull p = fpow(a, t, n), i = s;
while(p != 1 && p != n - 1 && a % n && i--)
p = mul(p, p, n);
if(p != n - 1 && i != s) return false;
}
return true;
}
ull pollard(ull n) {
auto f = [n](ull x) {return mul(x, x, n) + 1;};
ull x = 0, y = 0, t = 30, prd = 2, i = 1, q;
while(t++ % 40 || __gcd(prd, n) == 1) {
if(x == y) x = ++i, y = f(x);
if((q = mul(prd, max(x, y) - min(x, y), n))) prd = q;
x = f(x), y = f(f(y));
}
return __gcd(prd, n);
}
vi factor(ull n) {
if(n == 1) return {};
if(isPrime(n)) return {n};
ull x = pollard(n);
auto l = factor(x), r = factor(n / x);
for(auto x : r) l.emplace_back(x);
return l;
}
int T;
int main() {
read(T);
while(T--) {
ull n;
read(n);
vi fac = factor(n);
ull ans = 0;
for(auto i : fac) ans = max(ans, i);
if(ans == n) puts("Prime");
else printf("%llu\n",ans);
}
}
标签:prd,ch,return,Rho,Pollard,ull,ans,mul
From: https://www.cnblogs.com/DCH233/p/16890366.html