7#include "cplib/num/mmint.hpp"
8#include "cplib/num/prime.hpp"
9#include "cplib/port/bit.hpp"
16struct FactorizationResult {
17 std::vector<T> factors, prime_factors;
21template <
typename ModInt>
22typename ModInt::int_type pollard_rho_modint() {
23 using T =
typename ModInt::int_type;
24 const T n = ModInt::mod();
25 constexpr T m = std::numeric_limits<T>::digits;
27 ModInt c(0), y, q, x, ys;
35 for (T i = 0; i < r; i++) {
39 for (T i = 0; i < r; i++) {
42 if ((i + 1) % m == 0) {
50 if (g == 1 && r % m != 0) {
58 g =
gcd((ys - x).val(), n);
66void factorize_work(FactorizationResult<T>& result) {
67 T n = result.factors.back();
68 result.factors.pop_back();
71 result.prime_factors.push_back(n);
75 if (n < (1ull << 32)) {
76 f = mmint_by_modulus([](
auto mint) {
return pollard_rho_modint<decltype(mint)>(); }, uint32_t(n));
78 f = mmint_by_modulus([](
auto mint) {
return pollard_rho_modint<decltype(mint)>(); }, n);
81 result.factors.push_back(f);
82 result.factors.push_back(n / f);
99template <
typename T, std::enable_if_t<std::is_
unsigned_v<T>>* =
nullptr>
104 int twos = port::countr_zero(n);
105 impl::FactorizationResult<T> result;
106 result.prime_factors.insert(result.prime_factors.end(), twos, 2);
107 if (port::has_single_bit(n)) {
108 return result.prime_factors;
110 result.factors.push_back(n >> twos);
111 while (!result.factors.empty()) {
112 impl::factorize_work(result);
114 std::sort(result.prime_factors.begin(), result.prime_factors.end());
115 return result.prime_factors;
std::vector< T > factorize(T n)
Integer factorization.
Definition: factor.hpp:100
constexpr T gcd(T x, T y)
Greatest common divisor.
Definition: gcd.hpp:21
T prime_or_factor(T n)
Primality test and possibly return a non-trivial factor.
Definition: prime.hpp:123