Description

Given a n × n matrix A and a positive integer k, find the sum S = A + A2 + A3 + … + Ak.

Input

The input contains exactly one test case. The first line of input contains three positive integers n (n ≤ 30), k (k ≤ 109) and m (m < 104). Then follow n lines each containing nnonnegative integers below 32,768, giving A’s elements in row-major order.

Output

Output the elements of S modulo m in the same way as A is given.

Sample Input

2 2 4
0 1
1 1

Sample Output

1 2
2 3

Source

POJ Monthly--2007.06.03, Huang, Jinsong
 
令Sk = I + A + ... + A^k-1(I为单位矩阵)

求出Sk+1再减去I即可。

代码:

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
using namespace std;
int n,k,m;
void mul(int (*a)[60],int (*b)[60]) {
    int d[60][60] = {0};
    for(int i = 0;i < n * 2;i ++) {
        for(int j = 0;j < n * 2;j ++) {
            for(int k = 0;k < n * 2;k ++) {
                d[i][j] = (d[i][j] + a[i][k] * b[k][j]) % m;
            }
        }
    }
    for(int i = 0;i < n * 2;i ++) {
        for(int j = 0;j < n * 2;j ++) {
            a[i][j] = d[i][j];
        }
    }
}
void getans(int (*a)[60]) {
    int d[60][60];
    for(int i = 0;i < n * 2;i ++) {
        for(int j = 0;j < n * 2;j ++) {
            d[i][j] = a[i][j];
        }
    }
    while(k) {
        if(k % 2)mul(d,a);
        k /= 2;
        mul(a,a);
    }
    for(int i = n;i < n * 2;i ++) {
        for(int j = 0;j < n;j ++) {
            if(j)putchar(' ');
            printf("%d",i == j + n ? (d[i][j] + m - 1) % m : d[i][j]);
        }
        putchar('\n');
    }
}
int main() {
    int a[60][60] = {0};
    scanf("%d%d%d",&n,&k,&m);
    for(int i = 0;i < n;i ++) {
        for(int j = 0;j < n;j ++) {
            scanf("%d",&a[i][j]);
        }
    }
    for(int i = n;i < n * 2;i ++) {
        a[i][i - n] = a[i][i] = 1;
    }
    getans(a);
}