题目链接:hdu1575
题目大意:给一个矩阵A,求出A^k,结果对9973取余
思路:矩阵乘法
矩阵乘法具有结合律,因此A^4 = A * A * A * A = (A*A) * (A*A) = A^2 * A^2。我们可以得到这样的结论:当n为偶数时,A^n = A^(n/2) * A^(n/2);当n为奇数时,A^n = A^(n/2) * A^(n/2) * A (其中n/2取整)。这就告诉我们,计算A^n也可以使用二分快速求幂的方法。例如,为了算出A^25的值,我们只需要递归地计算出A^12、A^6、A^3的值即可。
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <cstdlib>
using namespace std;
int n,k;
struct node
{
int map[12][12];
}unit,s;
node Mul(node a,node b)
{
node c;
int i,j,k;
for(i = 0; i < n; i ++)
for(j = 0; j < n; j ++)
{
c.map[i][j] = 0;
for(k = 0; k < n; k ++)
c.map[i][j] += (a.map[i][k]*b.map[k][j])%9973;
c.map[i][j] %= 9973;
}
return c;
}
int pow(int k)
{
while(k)
{
if(k&1) unit = Mul(unit,s);
k >>= 1;
s = Mul(s,s);
}
int sum = 0;
for(int i = 0; i < n; i ++)
sum += unit.map[i][i], sum%= 9973;
return sum;
}
int main()
{
int i,j,T;
scanf("%d",&T);
while(T--)
{
scanf("%d%d",&n,&k);
for(i = 0; i < n; i ++)
for(j = 0; j < n; j ++)
scanf("%d",&unit.map[i][j]), s.map[i][j] = unit.map[i][j];
printf("%d\n",pow(k-1));//传参传的是k-1,而不是k
}
return 0;
}