开始搞一搞矩阵方面的东西把,第一个接触的快速矩阵幂,也是一个模版题,不过也不错,能加快对这个的理解。快速矩阵幂的学习:http://www.cnblogs.com/vongang/archive/2012/04/01/2429015.html点击打开链接
然后就是对这个的解法了,套用板子即可,只不过需要在计算出数据的时候记得MOD一下,不然就会出错的。
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int N = 15;
const int MOD=9973;
typedef long long ll;
struct Mat {
int mat[N][N];
};
int t;
ll k;
int n, m;
Mat a;
Mat operator * (Mat a, Mat b) {
Mat c;
memset(c.mat, 0, sizeof(c.mat));
int i, j, k;
for(k = 0; k < n; ++k) {
for(i = 0; i < n; ++i) {
if(a.mat[i][k] <= 0) continue; //***
for(j = 0; j < n; ++j) {
if(b.mat[k][j] <= 0) continue; //***
c.mat[i][j] = (c.mat[i][j]+a.mat[i][k] * b.mat[k][j]%MOD)%MOD;
}
}
}
return c;
}
Mat operator ^ (Mat a, ll k) {
Mat c;
int i, j;
for(i = 0; i < n; ++i)
for(j = 0; j < n; ++j)
c.mat[i][j] = (i == j);
for(; k; k >>= 1) {
if(k&1) c = c*a;
a = a*a;
}
return c;
}
Mat POW( Mat t,int k )//另外一种递归的写法,也蛮好理解的,分奇偶即可知道
{
if( k == 1 )
return t;
Mat t1 = POW( t, k/2 );
t1 = t1*t1;
if( k & 1 )
return t1 * t;
else
return t1;
}
int main() {
//freopen("data.in", "r", stdin);
int i;
double res;
scanf("%d",&t);
while(t--)
{
scanf("%d%lld",&n,&k);
for(int i=0;i<n;i++)
{
for(int j=0;j<n;j++)
{
scanf("%d",&a.mat[i][j]);
}
}
ll sum=0;
Mat tmp;
tmp=POW(a,k);//tmp=a^k;
for(int i=0;i<n;i++)
{
sum=(sum+tmp.mat[i][i])%MOD;
}
printf("%lld\n",sum%MOD);
}
return 0;
}