矩阵十题(2)
经典题目2
给定矩阵A,请快速计算出A^n(n个A相乘)的结果,输出的每个数都mod p。
由于矩阵乘法具有结合律,因此
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的值即可。根据这里的一些结果,我们可以在计算过程中不断取模,避免高精度运算。
hdu 1575 Tr A
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1575
题目大意:求矩阵A^k后的矩阵的主对角线上各项的和,结果mod 9973
思路:直接矩阵快速幂即可
代码如下:
1 #include<stdio.h> 2 #include<string.h> 3 #define N 11 4 struct Matrix 5 { 6 int a[N][N]; 7 }res,tmp,origin; 8 int n,m; 9 Matrix mul(Matrix x,Matrix y) 10 { 11 int i,j,k; 12 memset(tmp.a,0,sizeof(tmp.a)); 13 for(i=1;i<=n;i++) 14 for(j=1;j<=n;j++) 15 for(k=1;k<=n;k++) 16 { 17 tmp.a[i][j]+=(x.a[i][k]*y.a[k][j])%m; 18 tmp.a[i][j]%=m; 19 } 20 return tmp; 21 } 22 void quickpow(int k) 23 { 24 int i; 25 memset(res.a,0,sizeof(res.a)); 26 for(i=1;i<=n;i++) 27 res.a[i][i]=1; 28 while(k) 29 { 30 if(k&1) 31 res=mul(res,origin); 32 origin=mul(origin,origin); 33 k>>=1; 34 } 35 } 36 int main() 37 { 38 int t,i,j,k; 39 m=9973; 40 scanf("%d",&t); 41 while(t--) 42 { 43 scanf("%d%d",&n,&k); 44 for(i=1;i<=n;i++) 45 for(j=1;j<=n;j++) 46 scanf("%d",&origin.a[i][j]); 47 quickpow(k); 48 int sum=0; 49 for(i=1;i<=n;i++) //求主对角线上各项的和 50 sum+=res.a[i][i]; 51 printf("%d\n",sum%m); 52 } 53 return 0; 54 }
posted on 2013-05-16 11:36 jumpingfrog0 阅读(558) 评论(0) 编辑 收藏 举报