Nhân ma trận (Matrix Exponentiation)
Nhân ma trận nhanh (Matrix Exponentiation) tính trong với là kích thước ma trận — dùng để giải công thức truy hồi tuyến tính và đếm đường đi trong đồ thị trong .
Nhân ma trận
typedef vector<vector<long long>> Matrix;
const long long MOD = 1e9 + 7;
Matrix multiply(const Matrix& A, const Matrix& B) {
int n = A.size(), m = B[0].size(), p = B.size();
Matrix C(n, vector<long long>(m, 0));
for (int i = 0; i < n; i++)
for (int k = 0; k < p; k++) if (A[i][k])
for (int j = 0; j < m; j++)
C[i][j] = (C[i][j] + A[i][k] % MOD * B[k][j]) % MOD;
return C;
}
Matrix mat_pow(Matrix A, long long n) {
int sz = A.size();
Matrix result(sz, vector<long long>(sz, 0));
for (int i = 0; i < sz; i++) result[i][i] = 1; // identity
while (n > 0) {
if (n & 1) result = multiply(result, A);
A = multiply(A, A);
n >>= 1;
}
return result;
}
Ứng dụng 1: Fibonacci
:long long fibonacci(long long n) {
if (n <= 1) return n;
Matrix M = {{1, 1}, {1, 0}};
Matrix R = mat_pow(M, n - 1);
return R[0][0]; // F_n
}
Ứng dụng 2: Công thức truy hồi tuyến tính tổng quát
:// Tính a_n với công thức truy hồi bậc k
long long linear_recurrence(vector<long long> c, vector<long long> init, long long n) {
int k = c.size();
if (n < k) return init[n];
Matrix M(k, vector<long long>(k, 0));
for (int j = 0; j < k; j++) M[0][j] = c[j];
for (int i = 1; i < k; i++) M[i][i-1] = 1;
Matrix R = mat_pow(M, n - k + 1);
long long ans = 0;
for (int j = 0; j < k; j++)
ans = (ans + R[0][j] % MOD * init[k-1-j]) % MOD;
return ans;
}
Ứng dụng 3: Đếm đường đi độ dài trong đồ thị
= số đường đi độ dài đúng từ đến :
// Với ma trận kề A (N x N)
// Đường đi độ dài K từ s đến t:
Matrix A_k = mat_pow(adj_matrix, K);
long long paths = A_k[s][t];
Ứng dụng 4: DP trên đồ thị với bước cố định
Bài toán: đếm số cách đi bước trên đồ thị thỏa ràng buộc, dùng ma trận chuyển trạng thái.
Tối ưu: Cayley-Hamilton
Với công thức truy hồi bậc và rất lớn, có thể dùng Berlekamp-Massey tìm công thức rồi dùng Cayley-Hamilton để tính nhanh hơn .
Độ phức tạp
| Bài toán | Độ phức tạp |
|---|---|
| () | |
| Fibonacci thứ | |
| Truy hồi bậc | |
| Đường đi độ dài ( đỉnh) |
Khi nào dùng Matrix Exponentiation?
- Công thức truy hồi tuyến tính với .
- Đếm đường đi độ dài cố định trong đồ thị nhỏ.
- DP với trạng thái ít () nhưng số bước nhiều.
Bình luận