The decision table

SituationMethodCost
, one querytrial division to
Many queries, all linear sieve for the smallest prime factor per query
Pollard’s rho + Miller-Rabin
has a medium factor, up to 60 digitsECM
60-100 digit semiprimeQuadratic sieve
> 100 digitsGNFS

Trial division

vector<pair<long long,int>> factor(long long n) {
    vector<pair<long long,int>> f;
    for (long long p = 2; p * p <= n; p++) {
        if (n % p) continue;
        int e = 0;
        while (n % p == 0) { n /= p; e++; }
        f.push_back({p, e});
    }
    if (n > 1) f.push_back({n, 1});               // the remaining prime
    return f;
}

The final if is essential: after dividing out everything up to , whatever is left is a single prime (there can be at most one factor larger than ).

Smallest-prime-factor sieve — for many queries

vector<int> spf(N + 1);
for (int i = 2; i <= N; i++) {
    if (!spf[i]) for (int j = i; j <= N; j += i) if (!spf[j]) spf[j] = i;
}
// factor in O(log n)
while (n > 1) { int p = spf[n]; int e = 0; while (n % p == 0) { n /= p; e++; } f.push_back({p,e}); }

preprocessing, then each factorisation is — the right structure when the problem factors many numbers below .

Pollard’s rho + Miller-Rabin — the 64-bit answer

void factorRec(u64 n, map<u64,int>& f) {
    if (n == 1) return;
    if (isPrime(n)) { f[n]++; return; }           // Miller-Rabin
    u64 d = pollard(n);
    factorRec(d, f);
    factorRec(n / d, f);
}

Strip small primes by trial division first (up to a few thousand) — it removes most of the work and avoids rho’s weakness on tiny factors. See Pollard’s Rho.

Expected , which factors any 64-bit number in microseconds.

What factorisation unlocks

Once you have :

QuantityFormula
Number of divisors
Sum of divisors
Euler totient
Möbius if any , else
All divisorsrecursive product over exponents, of them
Carmichael lcm of
Is a perfect square?every even
Primitive root existence

Counting and summing divisors without factoring

Number of divisors for every :

for (int i = 1; i <= N; i++)
    for (int j = i; j <= N; j += i) d[j]++;

— the harmonic series. The same loop with += i computes .

This “for each , loop over its multiples” pattern is the workhorse of divisor problems and is worth recognising: it is , not .

Divisor bounds

max
240
1344
6720
103 680

So “enumerate all divisors and do something per divisor” is affordable even for , provided you can factor .

Special forms

  • — check each from 2 to , taking integer roots.
  • Difference of squares () — Fermat’s method; fast when ‘s factors are close to , useless otherwise.
  • — strip powers of two with __builtin_ctzll.
  • Factorials and binomials — do not factor the number; use Legendre’s formula for the exponent of in .

See also: Pollard’s Rho · Divisor Functions · Sieve Techniques