~/problems / Number theory / Matrix exponentiation

Basics: matrix multiply and matrix power

easy basics ~10 min

Every matrix-exponentiation trick (huge Fibonacci numbers, linear recurrences, counting walks in a graph) sits on two small functions. Write them once, generically, with every entry reduced modulo mod:

  1. mat_mul(A, B, mod) -> list[list[int]]: the product of an n × m matrix A and an m × p matrix B (lists of rows), entry (i, j) being Σ A[i][t] · B[t][j] over t, taken % mod.
  2. mat_pow(M, e, mod) -> list[list[int]]: M raised to the power e for a square k × k matrix, modulo mod. M^0 is the identity matrix. Use repeated squaring: e can be up to 10^18, so multiplying e times is hopeless, but only about log2(e) ≈ 60 squarings are needed.
mat_mul([[1, 2], [3, 4]], [[5, 6], [7, 8]], 1000)   # [[19, 22], [43, 50]]
mat_mul([[1, 2, 3]], [[4], [5], [6]], 10)          # [[2]]   (32 % 10)
mat_pow([[1, 1], [1, 0]], 10, 10**9 + 7)          # [[89, 55], [55, 34]]   (Fibonacci numbers)
mat_pow([[2, 0], [0, 3]], 0, 7)                   # [[1, 0], [0, 1]]

Don't modify the input matrices. Constraints: dimensions up to 8, 0 <= e <= 10^18, 1 <= mod <= 2·10^9, entries in [0, mod).

Show hint

Keep result = identity and base = M; while e > 0, if e & 1 do result = result · base, then base = base · base and e >>= 1.

Topic: Matrix exponentiation. Linear recurrences in O(k^3 log n).

0:00
Ctrl ' run · Ctrl ↵ submit
esc