templates/pollard-rho.cpp
compilable
$cat templates/pollard-rho
Pollard's Rho Factorization
Factorize 64-bit integers into primes using Pollard's Rho with Miller-Rabin primality testing.
#factorization#pollard-rho#number-theory#miller-rabin
Log in to track progress, save custom versions, and organize into collections.Log In
$cat source_code/
cpp
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());
ll mulmod(ll a, ll b, ll m) { return (__int128)a * b % m; }
ll powmod(ll a, ll d, ll m) {
ll res = 1; a %= m;
while (d > 0) {
if (d & 1) res = mulmod(res, a, m);
a = mulmod(a, a, m);
d >>= 1;
}
return res;
}
bool millerRabin(ll n) {
if (n < 2) return false;
if (n < 4) return true;
if (n % 2 == 0) return false;
ll d = n - 1; int s = 0;
while (d % 2 == 0) { d /= 2; s++; }
for (ll a : {2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37}) {
if (a >= n) continue;
ll x = powmod(a, d, n);
if (x == 1 || x == n - 1) continue;
bool comp = true;
for (int r = 1; r < s; r++) {
x = mulmod(x, x, n);
if (x == n - 1) { comp = false; break; }
}
if (comp) return false;
}
return true;
}
ll pollardRho(ll n) {
if (n % 2 == 0) return 2;
ll x = rng() % (n - 2) + 2, y = x;
ll c = rng() % (n - 1) + 1, d = 1;
while (d == 1) {
x = (mulmod(x, x, n) + c) % n;
y = (mulmod(y, y, n) + c) % n;
y = (mulmod(y, y, n) + c) % n;
d = __gcd(abs(x - y), n);
}
return d == n ? pollardRho(n) : d;
}
vector<ll> factorize(ll n) {
if (n <= 1) return {};
if (millerRabin(n)) return {n};
ll d = pollardRho(n);
auto a = factorize(d), b = factorize(n / d);
a.insert(a.end(), b.begin(), b.end());
sort(a.begin(), a.end());
return a;
}60 linesutf-8
$cat explanation_notes.md
notes_viewer --renderedmarkdown (math enabled)
Pollard's Rho
Factorize large integers (up to ) that are too big for trial division.