Purpose: Factor a polynomial over in expected — the randomized algorithm used by essentially every computer algebra system for large fields.

Three stages

Polynomial factorisation is standardly done in three passes, each stripping away one kind of structure.

1. Square-free factorisation (SFF)

Remove repeated factors. Since captures exactly the repeated part,

is recovered by repeated gcds with the derivative. Cost . (Watch for , which happens when is a -th power in characteristic ; then take the -th root.)

2. Distinct-degree factorisation (DDF)

Separate factors by their degree, using the identity

So for :

collects exactly the degree- irreducible factors. Divide them out and continue. Cost: per step, using repeated squaring to compute .

3. Equal-degree factorisation (EDF) — the Cantor-Zassenhaus step

Now is a product of irreducibles, all of degree . Split them randomly.

For odd : pick a random polynomial of degree and compute

In each CRT component , the value is or according to whether is a quadratic residue there — and these are independent across components. So the gcd captures a uniformly random non-empty proper subset with probability , and a couple of tries split .

For : use the trace map instead, which takes values 0 and 1 independently per component.

Code sketch

// split g, a product of k >= 2 irreducibles each of degree d, over F_p (p odd)
poly edf_split(const poly& g, int d, long long p) {
    while (true) {
        poly h = random_poly(deg(g) - 1);
        poly t = powmod_poly(h, (ipow(p, d) - 1) / 2, g);
        poly r = gcd(g, t - 1);
        if (deg(r) > 0 && deg(r) < deg(g)) return r;
    }
}

Complexity

  • SFF:
  • DDF: — usually the bottleneck; can be improved to with baby-step giant-step (von zur Gathen-Shoup)
  • EDF: expected
  • Overall:

Contest use: roots of a polynomial mod p

The single most common application. To solve :

  1. — this is the product of all linear factors, i.e. exactly the roots.
  2. Split with EDF at until every factor is linear.
  3. Read the roots off.

Total -ish, which handles in the thousands. It generalises Tonelli-Shanks (which is the case) to arbitrary polynomials.

Variants / Use Cases