Matrix Power Series
Time Limit: 3000MS | Memory Limit: 131072K | |
Total Submissions: 18889 | Accepted: 7982 |
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
解析:
k为偶数:sum(k) = (1+A^(k/2)) *( A+A^2+……+A^(k/2)) = (1+A^(k/2)) * sum(k/2)
k为奇数:sum(k) = (1+A^((k-1)/2)) * sum(k/2) + A^k
代码:
#include<cstdio>
using namespace std;
const int maxn=30;
struct tnode{
int m[maxn+5][maxn+5];
}st;
int n,m;
tnode multi(tnode x,tnode y)
{
int i,j,k;tnode c;
for(i=0;i<n;i++)
for(j=0;j<n;j++)
for(c.m[i][j]=k=0;k<n;k++)
c.m[i][j]+=x.m[i][k]*y.m[k][j];
for(i=0;i<n;i++)
for(j=0;j<n;j++)
c.m[i][j]%=m;
return c;
}
tnode pow(int k)
{
tnode c,a=st;
int i,j;
for(i=0;i<n;i++)
for(j=0;j<n;j++)
c.m[i][j]=(i==j);
while(k)
{
if(k&1)c=multi(c,a);
a=multi(a,a),k>>=1;
}
return c;
}
void add(tnode &x,tnode y)
{
int i,j;
for(i=0;i<n;i++)
for(j=0;j<n;j++)
x.m[i][j]+=y.m[i][j];
for(i=0;i<n;i++)
for(j=0;j<n;j++)
x.m[i][j]%=m;
}
tnode get(int k)
{
if(k==1)return st;
tnode c1=get(k/2);
tnode c2=multi(c1,pow(k/2));
add(c1,c2);
if(k&1)add(c1,pow(k));
return c1;
}
int main()
{
//freopen("1.in","r",stdin);
int i,j,k;
scanf("%d%d%d",&n,&k,&m);
for(i=0;i<n;i++)
for(j=0;j<n;j++)
scanf("%d",&st.m[i][j]),st.m[i][j]%=m;
tnode c=get(k);
for(i=0;i<n;i++)
{
for(j=0;j<n-1;j++)printf("%d ",c.m[i][j]);
printf("%d\n",c.m[i][n-1]);
}
return 0;
}