题目1443:Tr A
-
题目描述:
-
A为一个方阵,则Tr A表示A的迹(就是主对角线上各项的和),现要求Tr(A^k)%9973。
-
输入:
-
数据的第一行是一个T,表示有T组数据。
每组数据的第一行有n(2 <= n <= 10)和k(2 <= k < 10^9)两个数据。接下来有n行,每行有n个数据,每个数据的范围是[0,9],表示方阵A的内容。
-
输出:
-
对应每组数据,输出Tr(A^k)%9973。
-
样例输入:
-
2 2 2 1 0 0 1 3 99999999 1 2 3 4 5 6 7 8 9
-
样例输出:
-
2 2686
这里主要是用到了矩阵的快速幂,用二分求幂原理求解,只不过这里是用在了矩阵的K次幂上
贴个a^k的函数求解:
int ak(int a,int k){//二分求幂求解a^k int ans=1; k%=M; while(k!=0){ if(k%2==1){ ans*=a; } k=k/2; a*=a; } return ans; }
-
#include<stdio.h> #define M 9973 int main() { int n,c,i,j,k,d; int buf[11][11],a[11][11],b[11][11]; while(scanf("%d",&n)!=EOF) { while(n--) { scanf("%d%d",&c,&d); //其中n为矩阵阶数 for(i=0;i<c;++i){ for(j=0;j<c;++j){ scanf("%d",&buf[i][j]); if(i==j) a[i][j]=1; else a[i][j]=0; } } while(d!=0){ if(d%2==1) { for(i=0;i<c;++i) for(j=0;j<c;++j) b[i][j]=0; //b数组初始化 for(i=0;i<c;++i){ for(j=0;j<c;++j) for(k=0;k<c;++k) b[i][j]+=a[i][k]*buf[k][j]; //a=a*buf(矩阵) } for(i=0;i<c;++i) for(j=0;j<c;++j) a[i][j]=b[i][j]%9973; } d/=2; for(i=0;i<c;++i) for(j=0;j<c;++j) b[i][j]=0; //b数组初始化 for(i=0;i<c;++i) //buf=buf*buf(矩阵) { for(j=0;j<c;++j) for(k=0;k<c;++k) b[i][j]+=buf[i][k]*buf[k][j]; } for(i=0;i<c;++i) for(j=0;j<c;++j) buf[i][j]=b[i][j]%9973; } int ans=0; for(i=0;i<c;++i) ans=(ans+a[i][i])%M; printf("%d\n",ans); } } return 0; } /************************************************************** Problem: 1443 User: 952086097 Language: C++ Result: Accepted Time:10 ms Memory:1020 kb ****************************************************************/