首先我们来想一下计算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+27 = ?= (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('
');
73 }
74 putchar('
');
75 }
76 return 0;
77 }