一个 m × n m \times n m×n 的矩阵是一个由 m m m 行 n n n 列元素排列成的矩形阵列。即形如
A = [ a 11 a 12 ⋯ a 1 n a 21 a 22 ⋯ a 2 n ⋮ ⋮ ⋱ ⋮ a m 1 a m 2 ⋯ a m n ] . A = \begin{bmatrix} a_{1 1} & a_{1 2} & \cdots & a_{1 n} \\ a_{2 1} & a_{2 2} & \cdots & a_{2 n} \\ \vdots & \vdots & \ddots & \vdots \\ a_{m 1} & a_{m 2} & \cdots & a_{m n} \end{bmatrix} \text{.} A=⎣ ⎡a11a21⋮am1a12a22⋮am2⋯⋯⋱⋯a1na2n⋮amn⎦ ⎤.
本题中认为矩阵中的元素 a i j a_{i j} aij 是整数。
两个大小分别为 m × n m \times n m×n 和 n × p n \times p n×p 的矩阵 A , B A, B A,B 相乘的结果为一个大小为 m × p m \times p m×p 的矩阵。将结果矩阵记作 C C C,则
c i j = ∑ k = 1 n a i k b k j , ( 1 ≤ i ≤ m , 1 ≤ j ≤ p ). c_{i j} = \sum_{k = 1}^{n} a_{i k} b_{k j} \text{,\qquad($1 \le i \le m$, $1 \le j \le p$).} cij=k=1∑naikbkj,(1≤i≤m, 1≤j≤p).
而如果 A A A 的列数与 B B B 的行数不相等,则无法进行乘法。
可以验证,矩阵乘法满足结合律,即 ( A B ) C = A ( B C ) (A B) C = A (B C) (AB)C=A(BC)。
一个大小为 n × n n \times n n×n 的矩阵 A A A 可以与自身进行乘法,得到的仍是大小为 n × n n \times n n×n 的矩阵,记作 A 2 = A × A A^2 = A \times A A2=A×A。进一步地,还可以递归地定义任意高次方 A k = A × A k − 1 A^k = A \times A^{k - 1} Ak=A×Ak−1,或称 A k = A × A × ⋯ × A ⏟ k 次 A^k = \underbrace{A \times A \times \cdots \times A}_{k \text{ 次}} Ak=k 次 A×A×⋯×A。
特殊地,定义 A 0 A^0 A0 为单位矩阵 I = [ 1 0 ⋯ 0 0 1 ⋯ 0 ⋮ ⋮ ⋱ ⋮ 0 0 ⋯ 1 ] I = \begin{bmatrix} 1 & 0 & \cdots & 0 \\ 0 & 1 & \cdots & 0 \\ \vdots & \vdots & \ddots & \vdots \\ 0 & 0 & \cdots & 1 \end{bmatrix} I=⎣ ⎡10⋮001⋮0⋯⋯⋱⋯00⋮1⎦ ⎤。
给定 n × n n\times n n×n 的矩阵 A A A,求 A k A^k Ak。
第一行两个整数 n , k n,k n,k。
接下来 n n n 行,每行 n n n 个整数,第 i i i 行的第 j j j 的数表示 A i , j A_{i,j} Ai,j。
输出 A k A^k Ak
共 n n n 行,每行 n n n 个数,第 i i i 行第 j j j 个数表示 ( A k ) i , j (A^k)_{i,j} (Ak)i,j,每个元素对 1 0 9 + 7 10^9+7 109+7 取模。
2 1
1 1
1 1
1 1
1 1
【数据范围】
对于 100 % 100\% 100% 的数据, 1 ≤ n ≤ 100 1\le n \le 100 1≤n≤100, 0 ≤ k ≤ 1 0 12 0 \le k \le 10^{12} 0≤k≤1012, ∣ A i , j ∣ ≤ 1000 |A_{i,j}| \le 1000 ∣Ai,j∣≤1000。
1、矩阵维度是 n, n<= 100, 矩阵乘法复杂度就是 O(n^3) = O(10^6)
2、矩阵快速幂, k <= 10^12, 复杂度是 log2(10^12) = 40 左右,
则总体复杂度 O(10^7)
#include
#include
#include
using namespace std;
typedef long long ll;
const int MaxN = 110;
const int mod = 1000000007;
ll n, k;
struct matrix
{
ll c[MaxN][MaxN];
matrix()
{
memset(c, 0, sizeof c);
}
};
matrix R;
matrix multi(matrix& x, matrix& y)
{
matrix r;
for(int i = 1; i <= n; ++i)
{
for(int j = 1; j <= n; ++j)
{
for(int k = 1; k <= n; ++k)
{
r.c[i][j] += (x.c[i][k] % mod) * (y.c[k][j] % mod) % mod;
r.c[i][j] %= mod;
}
}
}
return r;
}
matrix quick_pow(matrix A, ll k)
{
matrix res;
for(int i = 1; i <= n; ++i)
res.c[i][i] = 1;
while(k)
{
if(k & 1)
{
res = multi(res, A);
}
A = multi(A, A);
k >>= 1;
}
return res;
}
int main()
{
scanf("%lld%lld", &n, &k);
for(int i = 1; i <= n; ++i)
{
for(int j = 1; j <= n; ++j)
{
scanf("%lld", &R.c[i][j]);
}
}
R = quick_pow(R, k);
for(int i = 1; i <= n; ++i)
{
for(int j = 1; j <= n; ++j)
{
printf("%lld", R.c[i][j]);
if(j == n)
printf("\n");
else
printf(" ");
}
}
return 0;
}
/*
2 1
1 1
1 1
*/
/*
1 1
1 1
*/
/*
2 3
*/
/*
1 2
2 1
*/