Time Limit: 3000MS | Memory Limit: 131072K | |
Total Submissions: 13486 | Accepted: 5816 |
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
对于任意的A^x,我们都能够利用矩阵快速幂求出,但是我们现在要求的是和。
仔细观察整个式子,那么我们可以对原式进行变形
如果k为偶数,那么(A+A^2+....A^K) = (A+...+A^K/2)+A^K/2*(A+...+A^K/2)
如果k为奇数,那么(A+A^2+....A^K) = (A+...+A^K/2)+A^K/2*(A+...+A^K/2)+A^k
//2136K 172MS
#include<stdio.h>
#define maxn 37
int M,n;
struct Matrax
{
int m[maxn][maxn];
}a,per;
void init()//建立矩阵
{
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
{
scanf("%d",&a.m[i][j]);
a.m[i][j]%=M;
per.m[i][j]=(i==j);
}
}
Matrax multi(Matrax a,Matrax b)//矩阵相乘
{
Matrax c;
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
{
c.m[i][j]=0;
for(int k=0;k<n;k++)
c.m[i][j]+=a.m[i][k]*b.m[k][j];
c.m[i][j]%=M;
}
return c;
}
Matrax power(int k)//矩阵快速幂
{
Matrax c,p,ans=per;
p=a;
while(k)
{
if(k&1){ans=multi(ans,p);k--;}
else {k/=2;p=multi(p,p);}
}
return ans;
}
Matrax add(Matrax a,Matrax b)//矩阵相加
{
Matrax c;
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
c.m[i][j]=(a.m[i][j]+b.m[i][j])%M;
return c;
}
Matrax MatraxSum(int k)//二分求和
{
if(k==1)return a;
Matrax tmp,b;
tmp=MatraxSum(k/2);
if(k&1)
{
b=power(k/2+1);
tmp=add(tmp,multi(tmp,b));
tmp=add(tmp,b);
}
else
{
b=power(k/2);
tmp=add(tmp,multi(tmp,b));
}
return tmp;
}
int main()
{
int k;
while(scanf("%d%d%d",&n,&k,&M)!=EOF)
{
init();
Matrax ans=MatraxSum(k);
for(int i=0;i<n;i++)
{
for(int j=0;j<n-1;j++)
printf("%d ",ans.m[i][j]%M);
printf("%d\n",ans.m[i][n-1]%M);
}
}
return 0;
}