题目大意
给出一个矩阵 A A A,求矩阵 S = A + A 2 + A 3 . . . . . . A k S=A+A^2+A^3......A^k S=A+A2+A3......Ak. 并模上一个数m
输入
第一行
n
,
k
,
m
n,k,m
n,k,m
接下来读入矩阵
A
A
A
输出
矩阵 S S S
矩阵乘法
如果A是一个数的情况,那我们可以得到这样一个矩阵:
同理。我们只要把其中的数字替换成一个矩阵即可。
其中,1替换为单位矩阵E。即左上到右下的斜角线为1,其余都为0的矩阵。
即,对于一个数k,有
(
k
∗
1
=
1
∗
k
=
k
)
(k*1=1*k=k)
(k∗1=1∗k=k),
而,对于一个矩阵A,有
(
A
∗
E
=
E
∗
A
=
A
)
(A*E=E*A=A)
(A∗E=E∗A=A).
最后答案中会多一个E出来(最开始的E),减去即可。
代码
#include<cstdio>
int n,m,k;
struct asdf{
int n,m,jz[100][100];
} A,B,C;
asdf operator *(asdf aa, asdf bb){
asdf cc;
cc.n = aa.n;
cc.m = bb.m;
for(int i = 1; i <= cc.n; ++i)
for(int j = 1 ;j <= cc.m; ++j)
cc.jz[i][j] = 0;
for(int l = 1; l <= aa.m; ++l)
for(int i = 1; i <= cc.n; ++i)
for(int j = 1; j <= cc.m; ++j)
cc.jz[i][j] = (cc.jz[i][j] + aa.jz[i][l] * bb.jz[l][j] % m) % m;
return cc;
}
void ksm(int now){
C = B;
while (now) {
if (now & 1) C = C * B;
B = B * B;
now /= 2;
}
}
int main(){
scanf("%d%d%d",&n,&k,&m);
A.n = A.m = n;
for(int i = 1; i <= n; ++i){
for(int j = 1; j <= n; ++j)
scanf("%d",&A.jz[i][j]);
}
B.n = B.m = 2*n;
for(int i = 1; i <= n; ++i){
B.jz[i][i+n] = B.jz[i+n][i+n] = 1;
for(int j = 1; j <= n; ++j)
B.jz[i][j] = A.jz[i][j] % m;
}
ksm(k);
for(int i = 1; i <= n; ++i){
for(int j = 1; j <= n; ++j){
if(i == j) printf("%d ",(C.jz[i][j+n]+m-1) % m);
else printf("%d ",C.jz[i][j+n]);
}
printf("\n");
}
}