普通版本的质因数分解:时间复杂度为 \(O(\sqrt{n})\),可以处理 \(n=1e10\)。
struct Avg{
i64 N;
vector<i64> preim;
vector<i64> cnt;
Avg(i64 N_) {
N = N_;
for (i64 i = 2; i <= N / i; i++) {
i64 sum = 0;
while (N % i == 0) sum++, N /= i;
if (sum) preim.push_back(i);
if (sum) cnt.push_back(sum);
}
if (N > 1) {
preim.push_back(N);
cnt.push_back(1);
}
}
};
稍微处理后的质因数分解:时间复杂度为 \(O(\frac{2\sqrt n}{ln(n)})\) ,最大可以处理 \(n=1e16\) 内的数。
struct pre{
int N;
vector<i64> preim;
vector<i64> a;
pre(int N_) : a(N_ + 1) {
N = N_;
for (i64 i = 2; i <= N; i++) {
if (!a[i]) {
a[i] = i;
preim.push_back(i);
}
for (auto p : preim) {
if (i * p > N) break;
a[i * p] = p;
if (a[i] == p) {
break;
}
}
}
}
};
pre t(M + 1);
struct Avg{
i64 N;
vector<i64> preim;
vector<i64> cnt;
Avg(i64 N_) {
N = N_;
for (auto p : t.preim) {
if (p * p > N) break;
i64 sum = 0;
while (N % i == 0) sum++, N /= i;
if (sum) preim.push_back(i);
if (sum) cnt.push_back(sum);
}
if (N > 1) {
preim.push_back(N);
cnt.push_back(1);
}
}
};
\(Pollard-Rho\) 筛:时间复杂度为 \(O(n^{\frac{1}{4}})\),可以处理 \(n=1e18\) 内的数。(用的jls的板子,嘻嘻)
struct MR{
inline i64 mul(i64 a, i64 b, i64 m) {
return static_cast<i128>(a) * b % m;
}
inline i64 qp(i64 a, i64 b, i64 m) {
i64 res = 1LL % m;
for (; b; b >>= 1LL, a = mul(a, a, m))
if (b & 1)
res = mul(res, a, m);
return res;
}
inline bool isprime(i64 n) {
if (n < 2)
return false;
static constexpr i64 A[] = {2, 3, 5, 7, 11, 13, 17, 19, 23};
i64 s = __builtin_ctzll(n - 1);
i64 d = (n - 1) >> s;
for (auto a : A) {
if (a == n)
return true;
i64 x = qp(a, d, n);
if (x == 1 || x == n - 1)
continue;
bool ok = false;
for (i64 i = 0; i < s - 1; ++i) {
x = mul(x, x, n);
if (x == n - 1) {
ok = true;
break;
}
}
if (!ok)
return false;
}
return true;
}
};
MR t;
struct PR{
inline i64 mul(i64 a, i64 b, i64 m) {
return static_cast<i128>(a) * b % m;
}
inline vector<i64> factorize(i64 n) {
vector<i64> p;
function<void(i64)> f = [&](i64 n) {
if (n <= 10000) {
for (i64 i = 2; i * i <= n; ++i)
for (; n % i == 0; n /= i)
p.push_back(i);
if (n > 1)
p.push_back(n);
return;
}
if (t.isprime(n)) {
p.push_back(n);
return;
}
auto g = [&](i64 x) {
return (mul(x, x, n) + 1) % n;
};
i64 x0 = 2LL;
while (true) {
i64 x = x0;
i64 y = x0;
i64 d = 1;
i64 power = 1LL, lam = 0LL;
i64 v = 1;
while (d == 1) {
y = g(y);
++lam;
v = mul(v, std::abs(x - y), n);
if (lam % 127LL == 0) {
d = std::gcd(v, n);
v = 1;
}
if (power == lam) {
x = y;
power *= 2LL;
lam = 0;
d = std::gcd(v, n);
v = 1;
}
}
if (d != n) {
f(d);
f(n / d);
return;
}
++x0;
}
};
f(n);
sort(p.begin(), p.end());
return p;
}
};
PR st;