矩阵十题(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 }
View Code

posted on 2013-05-16 11:36  jumpingfrog0  阅读(549)  评论(0编辑  收藏  举报

导航