Factor a polynomial into irreducibles. Over a finite field this is polynomial-time; over it reduces to the finite-field case plus lifting.

Over — the three stages

Every practical algorithm runs the same pipeline, each stage stripping away one kind of structure.

1. Square-free factorisation (SFF)

Remove repeated factors using :

. Watch for , which happens when is a -th power in characteristic — then take the -th root by dividing every exponent by .

2. Distinct-degree factorisation (DDF)

Separate factors by their degree, using

So collects exactly the degree- irreducible factors. Compute by repeated squaring: per step.

3. Equal-degree factorisation (EDF)

Now is a product of irreducibles all of degree . Split them randomly — see Cantor-Zassenhaus:

For odd , pick a random and compute . In each CRT component this value is independently, so the gcd captures a random proper subset with probability .

The algorithms

AlgorithmTypeTimeBest for
Berlekampdeterministicsmall (e.g. )
Cantor-Zassenhausrandomizedlarge — the standard
von zur Gathen-Shouprandomizedasymptotically better DDF
Kaltofen-Shouprandomizedtheoretical

Berlekamp’s advantage is that it reveals the number of factors immediately, as where is the Frobenius matrix — useful for irreducibility testing without factoring.

The contest use: roots modulo

By far the most common application. To solve :

  1. — the product of all linear factors, i.e. exactly the roots.
  2. Split with EDF at until every factor is linear.
  3. Read off the roots.
vector<long long> rootsModP(Poly f, long long p) {
    Poly xp = powmodPoly({0,1}, p, f, p);              // x^p mod f
    xp[1] = (xp[1] - 1 + p) % p;                       // x^p - x
    Poly g = polyGcd(f, xp, p);                        // product of linear factors
    vector<long long> res;
    edfSplit(g, 1, p, res);                            // recursively split
    return res;
}

This generalises Tonelli-Shanks (the case ) to arbitrary polynomials, and handles degrees in the thousands.

Over the integers

  1. Reduce mod a prime not dividing the leading coefficient or the discriminant.
  2. Factor over .
  3. Hensel lift the factorisation to with exceeding twice the Mignotte bound on any factor’s coefficients.
  4. Recombine — try products of the lifted factors and test whether they divide over .

Step 4 is exponential in the number of factors in the worst case (the “Swinnerton-Dyer” polynomials are the classic bad case). The LLL lattice-reduction algorithm makes the whole thing polynomial-time, which is the celebrated Lenstra-Lenstra-Lovász result.

Irreducibility testing

Cheaper than factoring:

TestMethod
Over for all dividing
Over , via Berlekamp
Over Eisenstein’s criterion: a prime divides all coefficients but the leading one, and
Over irreducible mod some prime ⟹ irreducible over (the converse fails)
Cyclotomic polynomialsalways irreducible over

The “irreducible mod implies irreducible over ” direction is a cheap and often sufficient test.

TaskMethod
Polynomial GCDEuclidean, ; half-GCD,
Resultantvia the Euclidean algorithm, or the Sylvester determinant
Discriminant
Squarefree test
Number of irreducible factorsBerlekamp’s rank computation
Number of monic irreducibles of degree over — the same Möbius formula as Lyndon words

See also: Cantor-Zassenhaus · Berlekamp · Hensel Lifting