Consider an n-by-n matrix A. We define Ak = A * A * ... * A (k times). Here, * denotes the usual matrix multiplication.
You are to write a program that computes the matrix A + A2 + A3 + ... + Ak.
Example
Suppose A = . Then A2 = = , thus:
Such computation has various applications. For instance, the above example actually counts all the paths in the following graph:
Input
Input consists of no more than 20 test cases. The first line for each case contains two positive integers n (≤ 40) and k (≤ 1000000). This is followed by n lines, each containing n non-negative integers, giving the matrix A.
Input is terminated by a case where n = 0. This case need NOT be processed.
Output
For each case, your program should compute the matrix A + A2 + A3 + ... + Ak. Since the values may be very large, you only need to print their last digit. Print a blank line after each case.
Sample Input
3 2 0 2 0 0 0 2 0 0 0 0 0
Sample Output
0 2 4 0 0 2 0 0 0
注意到K为偶数时有 A1 + A^2 + A^3 +.... A^k = (E + A^(k /2) (A ^ 1 + A ^ 2 + A ^ 3 + ...A ^ k / 2)
到K为奇数时把最后一想A^k单独提出剩下的为偶数
DFS即可
#include<iostream> #include<cstring> #include<cstdio> #include<cstdlib> using namespace std; #define MAXN 50 int n,K; struct node { int mat[MAXN][MAXN]; }; node calcu(node x, node y) { node ret; memset(ret.mat,0,sizeof(ret.mat)); for (int i = 1; i <= n ; i++) for (int j = 1; j <= n ; j++) { for (int k = 1; k <= n ; k++) ret.mat[i][j] = (ret.mat[i][j] + x.mat[i][k] * y.mat[k][j]) % 10; } return ret; } node add(node x,node y) { node ret; memset(ret.mat,0,sizeof(ret.mat)); for (int i = 1; i <= n ; i++) for (int j = 1; j <= n ; j++) { ret.mat[i][j] = x.mat[i][j] + y.mat[i][j]; ret.mat[i][j] %= 10; } return ret; } node pow_mat(node x,int cnt) { node ret; memset(ret.mat,0,sizeof(ret.mat)); for (int i = 1; i < MAXN ; i++) ret.mat[i][i] = 1; while (cnt) { if (cnt & 1) ret = calcu(ret,x); x = calcu(x,x); cnt >>= 1; } return ret; } node dfs(node cur, int k) { if (k == 1) return cur; node res = dfs(cur,k / 2); node ans; ans = add(res,calcu(res,pow_mat(cur,k / 2))); if (k & 1) ans = add(ans,pow_mat(cur,k)); return ans; } int main() { while (scanf("%d%d",&n,&K) != EOF) { if (n == 0) break; node ans; for (int i = 1; i <= n ; i++) for (int j = 1; j <= n ; j++) {scanf("%d",&ans.mat[i][j]); ans.mat[i][j] %= 10;} node ret = dfs(ans,K); for (int i = 1; i <= n ; i++) { printf("%d",ret.mat[i][1]); for (int j = 2; j <= n ; j++) printf(" %d",ret.mat[i][j]); putchar(' '); } putchar(' '); } return 0; }