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+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('\n'); 73 } 74 putchar('\n'); 75 } 76 return 0; 77 }
人生就像心电图,想要一帆风顺,除非game-over