UVA 11149 Power of Matrix

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('\n');
        }
        putchar('\n');
    }
    return 0;
}

  

posted @ 2015-03-14 11:06  Commence  阅读(149)  评论(0编辑  收藏  举报