Given the first terms and the coefficients, compute for enormous .
The methods
| Method | Time | When |
|---|---|---|
| Iterate | small | |
| Matrix exponentiation | ||
| Kitamasa | ||
| Bostan-Mori | large | |
| Closed form (characteristic roots) | distinct rational roots only |
For and : matrix exponentiation is operations, Kitamasa is . Both are fine; for only the latter two are.
The unifying idea
All three fast methods compute the same thing:
the characteristic polynomial. If , then
They differ only in how the polynomial multiplication is done: matrices (), schoolbook polynomials (), or FFT/NTT ().
Kitamasa
// f[0..k-1] initial terms, c[0..k-1] coefficients: f[n] = sum c[i] * f[n-1-i]
long long kitamasa(vector<long long> f, vector<long long> c, long long n, long long MOD) {
int k = f.size();
if (n < k) return f[n];
// multiply two polynomials mod C(x)
auto mulmod = [&](vector<long long> a, vector<long long> b) {
vector<long long> r(2*k - 1, 0);
for (int i = 0; i < k; i++)
for (int j = 0; j < k; j++)
r[i+j] = (r[i+j] + a[i] * b[j]) % MOD;
for (int i = 2*k - 2; i >= k; i--) // reduce mod C(x)
for (int j = 0; j < k; j++)
r[i - 1 - j] = (r[i - 1 - j] + r[i] * c[j]) % MOD;
r.resize(k);
return r;
};
vector<long long> res(k, 0), base(k, 0);
res[0] = 1; // x^0
if (k == 1) base[0] = c[0]; else base[1] = 1; // x
while (n) { if (n & 1) res = mulmod(res, base); base = mulmod(base, base); n >>= 1; }
long long ans = 0;
for (int i = 0; i < k; i++) ans = (ans + res[i] * f[i]) % MOD;
return ans;
}Finding the recurrence: Berlekamp-Massey
Often you do not know the recurrence — you can only compute the first few terms by brute force. Berlekamp-Massey recovers the shortest linear recurrence from terms in .
The combination is the point: brute-force the first ~200 terms, run Berlekamp-Massey to find the recurrence, then Kitamasa to jump to term .
This works astonishingly often. Sequences that satisfy a linear recurrence include:
- counts of walks in a fixed graph,
- tilings of a board,
- any DP with a fixed finite state set and constant transitions,
- determinants and permanents of banded matrices,
- many combinatorial counting sequences.
If your sequence has such a structure, you may not even need to understand it — just compute enough terms and let Berlekamp-Massey find the pattern.
Non-homogeneous recurrences
with a polynomial of degree : extend the state vector with and encode the binomial updates. The matrix grows to .
For , add to the state (one extra dimension, multiplied by each step).
Closed forms
If the characteristic polynomial has distinct roots , then
with the determined by the initial conditions. A repeated root of multiplicity contributes .
Useful when the roots are nice (Fibonacci’s ), but numerically dangerous for large and usually not worth it when a algorithm exists.
Sums of a linear recurrence
The prefix sum also satisfies a linear recurrence, of order : just add to the state vector with . So “sum the first terms” is the same problem.
See also: Kitamasa · Berlekamp-Massey · Matrix Exponentiation