矩阵A乘矩阵B是A的第i行向量乘以B的第j列向量的值放在结果矩阵的i行j列。因为矩阵乘法满足结合律,所以它可以与一般的快速幂算法同理使用。注意矩阵在乘的时候取模。
#include <cstdio> #include <cstring> #include <algorithm> using namespace std; #define ll long long const int MAX_N = 110; const ll P = 1e9 + 7; struct Matrix { ll A[MAX_N][MAX_N]; int N; Matrix(int n) { N = n; memset(A, 0, sizeof(A)); } void operator = (const Matrix& a) { memcpy(A, a.A, sizeof(a.A)); N = a.N; } void operator *= (const Matrix& a) { Matrix ans(N); for (int i = 1; i <= N; i++) for (int j = 1; j <= N; j++) for (int k = 1; k <= N; k++) ans.A[i][j] += (A[i][k] % P) * (a.A[k][j] % P) % P; *this = ans; } void operator %= (const ll x) { for (int i = 1; i <= N; i++) for (int j = 1; j <= N; j++) A[i][j] %= x; } void SetAnsUnit() { memset(A, 0, sizeof(A)); for (int i = 1; i <= N; i++) A[i][i] = 1; } bool Empty() { for (int i = 1; i <= N; i++) for (int j = 1; j <= N; j++) if (A[i][j]) return false; return true; } void Print() { for (int i = 1; i <= N; i++) { for (int j = 1; j <= N; j++) printf("%lld ", A[i][j]); printf(" "); } } }; Matrix Power(Matrix a, ll n) { Matrix ans(a.N); ans.SetAnsUnit(); while (n) { if (n & 1) { ans *= a; ans %= P; } a *= a; a %= P; n >>= 1; } return ans; } int main() { int n; long long k; scanf("%d%lld", &n, &k); static Matrix a(n); for (int i = 1; i <= n; i++) for (int j = 1; j <= n; j++) scanf("%d", &a.A[i][j]); Power(a, k).Print(); return 0; }