Tr A(矩阵快速幂)

来源:互联网 发布:重庆交通干部网络学校 编辑:程序博客网 时间:2024/05/21 22:53

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



#include<cstdio>#include<iostream>#include<cmath>#include<cstring>#include<algorithm>#define LL long longusing namespace std;const int MAX_N = 50;const int MOD = 9973;struct matrix{    LL m[MAX_N][MAX_N];};long long N,k;matrix res,a;matrix multi(matrix a,matrix b)//矩阵乘法 {    matrix tmp;    for(int i=1;i<=N;i++)        for(int j=1;j<=N;j++)        {            tmp.m[i][j]=0;            for(int k=1;k<=N;k++)                tmp.m[i][j]+=a.m[i][k]*b.m[k][j];            tmp.m[i][j]%=MOD;        }    return tmp;}matrix fast_mod(matrix a,int n)//矩阵快速幂 {    for(int i=1;i<=N;i++)        for(int j=1;j<=N;j++)            res.m[i][j]=(i==j);    while(n)    {        if(n&1) res=multi(res,a);        a=multi(a,a);        n>>=1;    }    return res;}int main(){    int t;    scanf("%d",&t);    while(t--)    {    /*  memset(res,0,sizeof(res));        memset(a,0,sizeof(a));*/        scanf("%lld%lld",&N,&k);        for(int i=1;i<=N;i++)        {            for(int j=1;j<=N;j++)            {                scanf("%d",&a.m[i][j]);            }        }        fast_mod(a,k);        long long ans=0;        for(int i=1;i<=N;i++)        {            ans+=(res.m[i][i]%MOD);        //  ans+=res.m[N-i-1][i];        }        printf("%lld\n",ans%MOD);    }    return 0;}