Purpose: Compute the determinant (or solve a linear system) over the integers with exact arithmetic and no intermediate coefficient blowup — a fraction-free variant of Gaussian elimination.

The Problem It Solves

Plain Gaussian elimination on an integer matrix introduces fractions, and clearing denominators makes entries grow exponentially in the matrix size. Bareiss’s insight: at every step, divide by the previous pivot, and the division is guaranteed to be exact.

The Recurrence

The numerator is the familiar elimination step; the denominator is the pivot from two steps back. The magic is that this quotient is always an integer.

Code

// exact integer determinant, O(n^3) operations
long long bareiss(vector<vector<long long>> a) {
    int n = a.size();
    long long prev = 1, sign = 1;
    for (int k = 0; k < n - 1; k++) {
        if (a[k][k] == 0) {                        // pivot
            int p = -1;
            for (int r = k + 1; r < n; r++) if (a[r][k]) { p = r; break; }
            if (p < 0) return 0;
            swap(a[k], a[p]); sign = -sign;
        }
        for (int i = k + 1; i < n; i++)
            for (int j = k + 1; j < n; j++)
                a[i][j] = (a[i][j] * a[k][k] - a[i][k] * a[k][j]) / prev;  // exact
        prev = a[k][k];
    }
    return sign * a[n-1][n-1];
}

Why the division is exact

Every intermediate equals a minor of the original matrix — specifically the determinant of the submatrix formed by rows and columns . This is Sylvester’s identity. Since minors are integers, and the recurrence computes exactly the next minor from the previous ones, the division must come out whole. ∎

That characterisation also bounds the entry sizes: by Hadamard’s inequality, a minor of a matrix with entries bounded by is at most , so the intermediate values are bits — polynomial, not exponential.

Complexity

  • Arithmetic operations: , the same count as Gaussian elimination
  • Bit complexity: with schoolbook big integers
  • Entry size: bits — versus exponential for naive fraction-clearing

When to use which

GoalMethod
Determinant mod a prime Gaussian elimination with modular inverses — simplest and fastest
Determinant mod a compositeGaussian elimination with a Euclidean-style row reduction (no inverses needed)
Exact integer determinantBareiss
Determinant of a huge integer matrixcompute mod several primes and CRT, with a Hadamard bound to know when to stop
Characteristic polynomialFaddeev-LeVerrier or the Hessenberg method

Contest advice

Most determinant problems ask for the answer modulo a prime, where plain modular Gaussian elimination is enough. Reach for Bareiss when the problem needs the exact value — for example counting spanning trees without a modulus, or lattice/volume computations.

Variants / Use Cases

  • Gaussian Elimination — the standard method
  • Matrix-Tree Theorem — exact spanning tree counts need exact determinants
  • Determinant — the topic page
  • Smith and Hermite normal forms — the other classical fraction-free integer matrix algorithms
  • Cramer’s rule with exact minors — Bareiss gives all the minors along the way