UVA-11149 Power of Matrix(矩阵二分幂)

题目大意:给一个n阶方阵,求A1+A2+A3+......Ak

题目分析:令F(k)=A1+A2+A3+......Ak。当k为偶数时,F(k)=F(k/2)*(E+Ak/2),k为奇数时,F(k)=F(k/2)*(E+Ak/2)+Ak。证明这两条公式也很简单,把这两条公式展开就行了。根据公式,递归即可。

 

代码如下:

 1 # include<iostream>
 2 # include<cstdio>
 3 # include<cstring>
 4 # include<algorithm>
 5 using namespace std;
 6 struct matrix
 7 {
 8     int r,c,m[45][45];
 9     matrix(int _r,int _c):r(_r),c(_c){}
10 };
11 matrix multiply(matrix a,matrix b)
12 {
13     matrix c(a.r,b.c);
14     for(int i=1;i<=c.r;++i){
15         for(int j=1;j<=c.c;++j){
16             c.m[i][j]=0;
17             for(int k=1;k<=a.c;++k){
18                 c.m[i][j]+=(a.m[i][k]%10)*(b.m[k][j]%10);
19                 c.m[i][j]%=10;
20             }
21         }
22     }
23     return c;
24 }
25 matrix mypow(matrix a,int n)
26 {
27     if(n==0){
28         for(int i=1;i<=a.r;++i)
29             for(int j=1;j<=a.c;++j)
30                 a.m[i][j]=(i==j)?1:0;
31         return a;
32     }
33     if(n==1)
34         return a;
35     matrix res=mypow(a,n/2);
36     res=multiply(res,res);
37     if(n&1)
38         res=multiply(res,a);
39     return res;
40 }
41 matrix add(matrix a,matrix b)
42 {
43     for(int i=1;i<=a.r;++i)
44         for(int j=1;j<=a.c;++j){
45             a.m[i][j]+=b.m[i][j];
46             a.m[i][j]%=10;///忘记取模,WA很多次。
47         }
48     return a;
49 }
50 matrix work(matrix mat,int k)
51 {
52     if(k==0){
53         for(int i=1;i<=mat.r;++i)
54             for(int j=1;j<=mat.c;++j)
55                 mat.m[i][j]=(i==j)?1:0;
56         return mat;
57     }
58     if(k==1)
59         return mat;
60     matrix res=work(mat,k/2);
61     matrix one(mat.r,mat.c);
62     for(int i=1;i<=one.r;++i)
63         for(int j=1;j<=one.c;++j)
64             one.m[i][j]=(i==j)?1:0;
65     one=add(one,mypow(mat,k/2));
66     res=multiply(res,one);
67     if(k&1)
68         res=add(res,mypow(mat,k));
69     return res;
70 }
71 int main()
72 {
73     int n,k;
74     while(scanf("%d%d",&n,&k)&&n)
75     {
76         matrix mat(n,n);
77         for(int i=1;i<=n;++i){
78             for(int j=1;j<=n;++j){
79                 scanf("%d",&mat.m[i][j]);
80                 mat.m[i][j]%=10;
81             }
82         }
83         matrix ans=work(mat,k);
84         for(int i=1;i<=ans.r;++i){
85             printf("%d",ans.m[i][1]);
86             for(int j=2;j<=ans.c;++j)
87                 printf(" %d",ans.m[i][j]);
88             printf("\n");///没注意格式,WA很多次!!!
89         }
90         printf("\n");
91     }
92     return 0;
93 }

 

posted @ 2015-08-18 17:48  20143605  阅读(569)  评论(0编辑  收藏  举报