Matrix Power Series
Time Limit: 3000MS | Memory Limit: 131072K | |
Total Submissions: 29036 | Accepted: 11805 |
Description
Given a n × n matrix A and a positive integer k, find the sum
Input
The input contains exactly one test case. The first line of input contains three positive integers n (n ≤ 30), k (k ≤ 10^9) and m (m < 10^4). Then follow n lines each containing n nonnegative 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
题目不长,就是要你求S % m,S是一个矩阵。要算的东西跟矩阵有关,而且还有幂,所以首先想到矩阵快速幂,但如果直接暴力算,即把A^1, A^2,...,A^k用矩阵快速幂算出来,然后在加一起,显然会超时。所以不妨换个思路,我们尝试构造下面的矩阵
其中A为题目所给的矩阵(n * n),O为n阶零矩阵,E为n阶单位阵。
然后尝试计算
....
是不是发现,要求的矩阵S就是矩阵的左下角的子矩阵然后在减去一个单位阵E
有了思路代码实现就很简单了
C++代码
#include <iostream>
#include <stdio.h>
#include <string.h>
#define N 64
using namespace std;
int n, m;
struct Matrix{
int _[N][N];
Matrix() {
memset(_, 0, sizeof(_));
}
};
//矩阵相乘
Matrix matrixMultiply(Matrix &A, Matrix &B) {
Matrix C;
for (int i = 0; i< 2*n; i++)
for (int j = 0; j< 2*n; j++)
for (int k = 0; k< 2*n; k++)
C._[i][k] = (C._[i][k] % m + (A._[i][j] % m * B._[j][k] % m) % m) % m;
return C;
}
//矩阵快速幂
Matrix matrixPower(Matrix &A, long long k) {
Matrix E;
for (int i = 0; i< 2*n; i++)
E._[i][i] = 1;
while (k != 0) {
if (k % 2) E = matrixMultiply(E, A);
A = matrixMultiply(A, A);
k /= 2;
}
return E;
}
int main() {
long long k;
while (scanf("%d%lld%d", &n, &k, &m) == 3) {
int A[32][32];
for (int i = 0; i< n; i++)
for (int j = 0; j< n; j++)
scanf("%d", &A[i][j]);
int E[32][32];
memset(E, 0, sizeof(E));
for (int i = 0; i< n; i++)
E[i][i] = 1;
Matrix S;
for (int i = 0; i< n; i++)
for (int j = 0; j< n; j++)
S._[i][j] = A[i][j];
for (int i = n; i< 2*n; i++)
for (int j = 0; j< n; j++)
S._[i][j] = E[i - n][j];
for (int i = n; i< 2*n; i++)
for (int j = n; j< 2*n; j++)
S._[i][j] = E[i - n][j - n];
S = matrixPower(S, k + 1);
for (int i = n; i< 2*n; i++){
for (int j = 0; j< n; j++){
S._[i][j] - E[i - n][j] < 0 ? printf("%d ", m - 1) : printf("%d ",S._[i][j] - E[i - n][j]);
}
printf("\n");
}
}
return 0;
}