Matrix Power Series
Time Limit: 3000MS | | Memory Limit: 131072K |
Total Submissions: 22502 | | Accepted: 9434 |
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
【分析】
练手题...二分递归加快计算
【代码】
//poj 3233 Matrix Power Series
#include<cstdio>
#include<cstring>
#include<iostream>
#define ll long long
#define fo(i,j,k) for(int i=j;i<=k;i++)
using namespace std;
int n,m,p;
struct matrix
{
int a[35][35];
matrix operator * (const matrix &x) const
{
matrix res;
fo(i,1,n)
fo(j,1,n)
{
res.a[i][j]=0;
fo(k,1,n)
res.a[i][j]=(res.a[i][j]+a[i][k]*x.a[k][j])%p;
}
return res;
}
matrix operator + (const matrix &x) const
{
matrix res;
fo(i,1,n)
fo(j,1,n)
res.a[i][j]=(a[i][j]+x.a[i][j])%p;
return res;
}
}base,now;
matrix get(int k)
{
k--;
base=now;
matrix tmp=now;
while(k)
{
while((k&1)==0) base=base*base,k>>=1;
tmp=tmp*base;
base=base*base,k>>=1;
}
return tmp;
}
matrix sum(int k)
{
if(k==1) return now;
matrix tmp=sum(k>>1);
if(k&1) return get(k>>1)*tmp+tmp+get(k);
return get(k>>1)*tmp+tmp;
}
int main()
{
scanf("%d%d%d",&n,&m,&p);
fo(i,1,n)
fo(j,1,n)
{
scanf("%d",&now.a[i][j]);
now.a[i][j]%=p;
}
matrix ans=sum(m);
fo(i,1,n)
{
fo(j,1,n)
printf("%d ",ans.a[i][j]%p);
printf("\n");
}
return 0;
}