Matrix Power Series
Time limit 3000 ms Memory limit 131072 kB
Problem 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
题解:矩阵快速幂+等比数列二分求和取模
代码如下:
#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
int n, k, m;
struct Matrix
{
int h[31][31];
};
Matrix A, ans, res, E;
Matrix Mul(Matrix a, Matrix b)
{
Matrix temp;
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
temp.h[i][j]=0;
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
for(int k=1;k<=n;k++){
temp.h[i][j]+=a.h[i][k]*b.h[k][j];
temp.h[i][j]%=m;
}
}
}
return temp;
}
Matrix Add(Matrix a, Matrix b)
{
Matrix temp;
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
temp.h[i][j]=(a.h[i][j]%m+b.h[i][j]%m)%m;
return temp;
}
Matrix quickpower(int k)
{
ans=A;
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
if(i==j)
res.h[i][j]=1;
else
res.h[i][j]=0;
}
}
while(k){
if(k&1)
res=Mul(res, ans);
ans=Mul(ans, ans);
k=k>>1;
}
return res;
}
Matrix quicksum(Matrix a,int k, int m)
{
if(k==1)
return a;
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
if(i==j)
E.h[i][j]=1;
else
E.h[i][j]=0;
}
}
if(k%2==0)
return Mul((Add(E,quickpower(k/2))),quicksum(a, k/2, m));
else
return Add(quickpower(k),Mul((Add(E,quickpower((k-1)/2))),quicksum(a, (k-1)/2, m)));
}
int main()
{
scanf("%d%d%d", &n, &k, &m);
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
scanf("%d", &A.h[i][j]);
}
}
Matrix f=quicksum(A, k, m);
for(int i=1;i<=n;i++){
for(int j=1;j<n;j++){
printf("%d ", f.h[i][j]);
}
printf("%d\n", f.h[i][n]);
}
return 0;
}