hdu 1575 Tr A
Problem Description
A为一个方阵,则Tr A表示A的迹(就是主对角线上各项的和),现要求Tr(A^k)%9973。
Input
数据的第一行是一个T,表示有T组数据。每组数据的第一行有n(2 <= n <= 10)和k(2 <= k < 10^9)两个数据。接下来有n行,每行有n个数据,每个数据的范围是[0,9],表示方阵A的内容。
Output
对应每组数据,输出Tr(A^k)%9973。
Sample Input
2
2 2
1 0
0 1
3 99999999
1 2 3
4 5 6
7 8 9
Sample Output
2
2686
解题思路:简单的矩阵快速幂。矩阵快速幂中初始化的矩阵就等同于普通快速幂初始化的1,这就是单位矩阵B,性质:B*A=A,即一开始若二进制最低位为1时,要先与初始的矩阵a相乘可得到a原矩阵,这和普通快速幂是一样的,就是1*a=a。单位矩阵就是主对角线都是1,其他全是0,以后当循环到二进制的最低位为1,矩阵b就和此时的矩阵('a')相乘即可。
AC代码:
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int mod=9973; 4 const int maxn=15; 5 struct Matrix{int m[maxn][maxn];}init; 6 int t,n,k; 7 Matrix mul(Matrix a,Matrix b){ 8 Matrix c; 9 for(int i=0;i<n;i++){//枚举第一个矩阵的行。 10 for(int j=0;j<n;j++){//枚举第二个矩阵的列。 11 c.m[i][j]=0; 12 for(int k=0;k<n;k++)//枚举第一个矩阵的列数 13 c.m[i][j]=(c.m[i][j]+a.m[i][k]*b.m[k][j])%mod; 14 } 15 } 16 return c; 17 } 18 Matrix POW(Matrix a,int x){//矩阵快速幂模仿一般快速幂,x为幂指数 19 Matrix b;memset(b.m,0,sizeof(b.m));//先初始化为0,再构造单位矩阵 20 for(int i=0;i<n;++i)b.m[i][i]=1; 21 while(x){ 22 if(x&1)b=mul(b,a);//如果x的二进制最低位为1,则乘上A^(2^i) 23 a=mul(a,a);//将矩阵a平方 24 x>>=1; 25 } 26 return b; 27 } 28 int main(){ 29 while(cin>>t){ 30 while(t--){ 31 cin>>n>>k; 32 for(int i=0;i<n;++i) 33 for(int j=0;j<n;++j) 34 cin>>init.m[i][j]; 35 Matrix res=POW(init,k);//矩阵快速幂取模运算 36 int ans=0; 37 for(int i=0;i<n;++i)//主对角线上各项的和 38 ans=(ans+res.m[i][i])%mod; 39 cout<<ans<<endl; 40 } 41 } 42 return 0; 43 }