题目:Tr A
分析:矩阵快速幂,基本原理与二分求幂相同,只不过把二分求幂的数相乘换为矩阵相乘,只需要把矩阵乘法的算法写出来即可,其中也用了上一篇文章使用的求模公式
代码如下:
#include <stdio.h>
#define M 9973
//矩阵乘法 ,第一个参数矩阵存放最后结果
void cal(int m1[12][12],int m2[12][12],int n)
{
int res [12][12];//暂存最终结果
int i,j,k;
for(j=1;j<=n;j++)
{
for(i=1;i<=n;i++)
{ int sum=0;
//行列对应元素相乘相加
for(k=1;k<=n;k++)
{ //同样使用了那两个求模公式
sum=(sum%M+(m1[i][k]%M)*(m2[k][j]%M)%M)%M;
}
res[i][j]=sum;
}
}
for(i=1;i<=n;i++)
{
for(j=1;j<=n;j++)
{
m1[i][j]=res[i][j];
}
}
}
int mat[12][12];
int ans[12][12];
int main(int argc, char** argv) {
int T;
scanf("%d",&T);
while(T--)
{
int n,k;
scanf("%d%d",&n,&k);
int i,j;
//初始化ans为单位矩阵,单位矩阵为除了对角线元素全为1,其他均为0的矩阵
for(i=1;i<=n;i++)
{
for(j=1;j<=n;j++)
{
if(i==j)
ans[i][j]=1;
else
ans[i][j]=0;
}
}
//给矩阵赋值
for(i=1;i<=n;i++)
{
for(j=1;j<=n;j++)
{
scanf("%d",&mat[i][j]);
}
}
//矩阵快速幂
while(k!=0)
{
if(k%2==1)
{
cal(ans,mat,n);
}
cal(mat,mat,n);
k/=2;
}
int tr=0;
for(i=1;i<=n;i++)
{
tr+=ans[i][i];
}
printf("%d\n",tr%9973);
}
return 0;
}