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
题意:求(A^k)%9973 的主对角线之和。
题解:矩阵快速幂的简单应用,可以说是模板题了。详细请见代码。
C++:
#include <iostream>
#include <cstring>
using namespace std;
const int mod=9973;
int n,m;
struct hh{
int a[15][15];
}x;//开一个二维数组表示矩阵
hh mul(hh x,hh y,int c){// 矩阵乘法公式
hh w;
memset(w.a,0,sizeof(w.a));
for (int i = 0; i < n;i++){
for (int j = 0; j < n;j++){
for (int k = 0; k < n;k++){
w.a[i][j]=(w.a[i][j]%c+(((x.a[i][k]%c)*(y.a[k][j]%c))%c)%c)%c;
}// 模运算公式(a+b)%c=(a%c+b%c)%c和(a*b)%c=((a%c)*(b%c))%c,当然这里可以简化写。
}// 简化写的形式为 w.a[i][j]=(w.a[i][j]%c+(x.a[i][k]%c)*(y.a[k][j]%c)%c)%c;
}
return w;
}
hh j_quick(hh a,int b,int c){// 矩阵快速幂(注意与普通快速幂的区别与联系)
hh ans;
memset(ans.a,0,sizeof(ans.a));
for (int i = 0; i < n;i++){// 相当于普通快速幂的 ans=1;
ans.a[i][i]=1;
}
while(b!=0){
if(b&1) ans=mul(ans,a,c);// 相当于普通快速幂的 ans=(ans*a)%c;
b>>=1;
a=mul(a,a,c);// 相当于普通快速幂的 a=(a*a)%c;
}
return ans;
}
int main(){
int t;
cin >> t;
while(t--){
cin >> n >> m;
for (int i = 0; i < n;i++){//输入矩阵
for (int j = 0; j < n;j++){
cin >> x.a[i][j];
}
}
hh z=j_quick(x,m,mod);
int sum=0;
for (int i = 0; i < n;i++){//计算对角线之和
sum=(sum%mod+z.a[i][i]%mod)%mod;// 模运算公式 (a+b)%c=(a%c+b%c)%c
}
cout << sum << endl;
}
return 0;
}
java: 解释同上
import java.util.*;
public class Main {
static Scanner cin = new Scanner(System.in);
static int n,k;
static class hh{
long [][] ma = new long [n+2][n+2];
public hh() {
for (int i = 0; i < n;i++) {
for (int j = 0; j < n;j++) {
ma[i][j]=0;
}
}
}
}
static hh mul(hh a, hh b,long x) {
hh c = new hh();
for (int i = 0; i < n;i++) {
for (int j = 0; j < n;j++) {
for (int k = 0;k < n;k++) {
c.ma[i][j]=(c.ma[i][j]+a.ma[i][k]*b.ma[k][j]%x)%x;
}
}
}
return c;
}
static hh quick(hh a,long w,long c) {
hh tmp = new hh();
for (int i = 0; i < n;i++) tmp.ma[i][i]=1;
while(w!=0) {
if(w%2==1) tmp=mul(tmp,a,c);
w/=2;
a=mul(a,a,c);
}
return tmp;
}
public static void main(String[] args){
long t;
t=cin.nextLong();
while(t-->0) {
n = cin.nextInt();
k = cin.nextInt();
hh a = new hh();
hh b = new hh();
for (int i = 0; i < n;i++) {
for (int j = 0; j < n;j++) {
a.ma[i][j]=cin.nextLong();
}
}
b=quick(a,k,9973);
long sum=0;
for (int i = 0; i < n;i++) {
sum=(sum%9973+b.ma[i][i]%9973)%9973;
}
System.out.println(sum%9973);
}
}
}