UVA11149 矩阵快速幂

先我们来想一下计算A+A^2+A^3...+A^k。

如果A=2,k=6。那你怎么算                        

2+22+23+24+25+26 = ?= (2+22+23)*(1+23)

如果A=2,k=7。那你怎么算                        

2+22+23+24+25+26+2= ?= (2+22+23)*(1+23)+27

so....同理:

当k是偶数,A+A^2+A^3...+A^k=(E+A^(k/2))*(A+A^2...+A^(k/2))。

当k是奇数,A+A^2+A^3...+A^k=(E+A^(k/2))*(A+A^2...+A^(k/2))+A^k。

 1 #include<iostream>
 2 #include<cstring>
 3 #include<cstdio>
 4 #include<cstdlib>
 5 using namespace std;
 6 #define MAXN 50
 7 int n,K;
 8 struct node
 9 {
10     int mat[MAXN][MAXN];
11 };
12 node calcu(node x, node y)
13 {
14     node ret;
15     memset(ret.mat,0,sizeof(ret.mat));
16     for (int i = 1; i <= n ; i++)
17         for (int j = 1; j <= n ; j++)
18     {
19         for (int k = 1; k <= n ; k++)
20             ret.mat[i][j] = (ret.mat[i][j] + x.mat[i][k] * y.mat[k][j]) % 10;
21     }
22     return ret;
23 }
24 node add(node x,node y)
25 {
26     node ret;
27     memset(ret.mat,0,sizeof(ret.mat));
28     for (int i = 1; i <= n ; i++)
29         for (int j = 1; j <= n ; j++)
30    {
31            ret.mat[i][j] = x.mat[i][j] + y.mat[i][j];
32            ret.mat[i][j] %= 10;
33    }
34    return ret;
35 }
36 node pow_mat(node x,int cnt)
37 {
38     node ret;
39     memset(ret.mat,0,sizeof(ret.mat));
40     for (int i = 1; i < MAXN ; i++) ret.mat[i][i] = 1;
41     while (cnt)
42     {
43         if (cnt & 1) ret = calcu(ret,x);
44         x = calcu(x,x);
45         cnt >>= 1;
46     }
47     return ret;
48 }
49 node dfs(node cur, int k)
50 {
51     if (k == 1) return cur;
52     node res = dfs(cur,k / 2);
53     node ans;
54     ans = add(res,calcu(res,pow_mat(cur,k / 2)));
55     if (k & 1) ans = add(ans,pow_mat(cur,k));
56     return ans;
57 }
58 int main()
59 {
60     while (scanf("%d%d",&n,&K) != EOF)
61     {
62         if (n == 0) break;
63         node ans;
64         for (int i = 1; i <= n ; i++)
65                 for (int j = 1; j <= n ; j++) {scanf("%d",&ans.mat[i][j]); ans.mat[i][j] %= 10;}
66         node ret = dfs(ans,K);
67         for (int i = 1; i <= n ; i++)
68         {
69                 printf("%d",ret.mat[i][1]);
70                 for (int j = 2; j <= n ; j++)
71                         printf(" %d",ret.mat[i][j]);
72                 putchar('\n');
73         }
74         putchar('\n');
75     }
76     return 0;
77 }

 

posted @ 2015-03-27 15:47  一麻袋码的玛侬  阅读(153)  评论(0编辑  收藏  举报