d a t e : 2023.1.10 date:2023.1.10 date:2023.1.10
如果觉得好就给个赞吧
博客没有赞,作者两行泪
先放道模版题
P3390 【模板】矩阵快速幂
1.认识矩阵
矩阵是一个数字阵列,一个二维数组, n n n 行 m m m 列的阵列称为 n × m n \times m n×m 矩阵。如果 n = m n=m n=m 则称为方阵。
2.矩阵乘法
矩阵乘法中第一个矩阵的列要等于第二个矩阵的行,两个大小分别为 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≤i≤m$, $1≤j≤p$)}
cij=k=1∑naikbkj,(1≤i≤m, 1≤j≤p)
可以证明,矩阵乘法满足结合律,即
(
A
B
)
C
=
A
(
B
C
)
(AB)C=A(BC)
(AB)C=A(BC)。
这里介绍一个特殊的矩阵——单位矩阵
单位矩阵,除了对角线为1,其他位置为0的矩阵。类似乘法中的1。 如下
1 0 0 0
0 1 0 0
0 0 1 0
0 0 0 1
任何一个矩阵乘上一个单位矩阵都保持不变。单位矩阵在矩阵快速幂中有应用。
3.矩阵快速幂
如果理解了矩阵乘法,那么快速幂也就很简单了,就是在快速幂的基础上改成矩阵就行了。
献上代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#define int long long
const int N = 105;
const int mod = 1e9+7;
int n,k;
struct Matrix {
int m[N][N];
Matrix() { memset(m, 0, sizeof(m)); }
};
Matrix mul(Matrix a, Matrix b) {
Matrix c;
for(int i=1;i<=n;i++) {
for(int j=1;j<=n;j++) {
for(int k=1;k<=n;k++) {
c.m[i][j]=(c.m[i][j]+(a.m[i][k]*b.m[k][j])%mod)%mod;
}
}
}
return c;
}
Matrix qpow(Matrix a, long long b) {
Matrix c;
for(int i=1;i<=n;i++) c.m[i][i]=1;
while(b) {
if(b&1) c=mul(c,a);
a=mul(a,a);
b>>=1;
}
return c;
}
Matrix a;
signed main() {
scanf("%lld%lld", &n, &k);
for(int i=1;i<=n;i++) {
for(int j=1;j<=n;j++) scanf("%lld", &a.m[i][j]);
}
a=qpow(a,k);
for(int i=1;i<=n;i++) {
for(int j=1;j<=n;j++) printf("%lld ", a.m[i][j]);
printf("\n");
}
}