Matrix Power Series
- Time Limit: 3000MS
- Memory Limit: 131072K
- Total Submissions: 27095
- Accepted: 11048
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 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
Source
POJ Monthly–2007.06.03, Huang, Jinsong
#include<iostream>
#include<cstdio>
using namespace std;
typedef long long ll;
typedef struct {
ll m[120][120];
} Matrix;
ll n,k,mod;
Matrix Mul(Matrix a, Matrix b) {
Matrix c;
memset(c.m, 0, sizeof(c.m));
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.m[i][j] = (c.m[i][j] + (a.m[i][k] * b.m[k][j]) % mod ) % mod;
}
}
}
return c;
}
Matrix solve(Matrix a, Matrix b) {
Matrix c;
memset(c.m, 0, sizeof(c.m));
for (int i = 0; i < n; i++) {
for (int j = 0; j < 2*n; j++) {
for (int k = 0; k < 2*n; k++) {
c.m[i][j] = (c.m[i][j] + (a.m[i][k] * b.m[k][j]) % mod ) % mod;
}
}
}
return c;
}
Matrix fastm(Matrix a, ll num) {
Matrix res;
memset(res.m, 0, sizeof(res.m));
for(int i=0; i<2*n; i++)
res.m[i][i]=1;
while (num) {
if (num & 1)
res = Mul(res, a);
num >>= 1;
a = Mul(a, a);
}
return res;
}
int main() {
Matrix a;
memset(a.m,0,sizeof(a.m));
scanf("%lld%lld%lld",&n,&k,&mod);
for(int i=0; i<n; i++) {
for(int j=0; j<n; j++) {
scanf("%lld",&a.m[i][j]);
a.m[i][j]=a.m[i][j]%mod;
}
}
Matrix b;
memset(b.m,0,sizeof(b.m));
for(int i=0; i<n; i++)
for(int j=0; j<n; j++)
b.m[i][j]=a.m[i][j];
for(int i=0; i<n; i++)
for(int j=n; j<2*n; j++)
b.m[i][j]=0;
for(int i=n; i<2*n; i++)
for(int j=0; j<n; j++)
b.m[i][j]=a.m[i-n][j];
for(int i=n; i<2*n; i++)
b.m[i][i]=1;
for(int i=0; i<n; i++)
a.m[i][i+n]=1;
b=fastm(b,k-1);
Matrix ans=solve(a,b);
for(int i=0; i<n; i++) {
printf("%lld",ans.m[i][0]);
for(int j=1; j<n; j++) {
printf(" %lld",ans.m[i][j]);
}
printf("\n");
}
return 0;
}
“`