T i m e Time Time L i m i t : Limit: Limit: 3000 M S 3000MS 3000MS
M e m o r y Memory Memory L i m i t : Limit: Limit: 131072 K 131072K 131072K
Description
l i n k link link
Given a n × n n × n n×n matrix A A A and a positive integer k k k, find the sum S = A + A 2 + A 3 + … + A k S = A + A^2 + A^3 + … + A^k 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
analysis:
Direct calculation will overtime consider the matrix [A i − 1, S i − 2] [A^{i-1},S_{i-2}][Ai−1,Si−2]
[ A i , S i − 1 ] = [ A i − 1 , S i − 2 ] ∗ F [A^i,S_{i-1}]=[A^{i-1},S_{i-2}]*F [Ai,Si−1]=[Ai−1,Si−2]∗F
F F F is thetransformation matrix,thenFFF :
A, EA, EA,E
O, E O, E O ,E
其中EEE represents theidentity matrix OOO is all0 00 matrix.
Note that theinitial matrixconstruction should beexpanded toconstruct
SSS is in theinitial matrix[1] [2] [1][2][1][2]
CODE:
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
typedef long long ll;
ll n,mod,k;
struct matrix{
ll n,m;
ll F[101][101];
}A,B,C;
matrix operator *(matrix a,matrix b)
{
matrix c;
c.n=a.n;c.m=a.m;
for(int i=1;i<=c.n;i++)
for(int j=1;j<=c.m;j++)
c.F[i][j]=0;
for(int k=1;k<=a.m;k++)
for(int i=1;i<=c.n;i++)
for(int j=1;j<=c.m;j++)
c.F[i][j]=(c.F[i][j]+a.F[i][k]*b.F[k][j]%mod)%mod; //矩阵乘法
return c;
}
void ksm(ll x)
{
if(x==1){
B=A;
return;
}
ksm(x/2);
B=B*B;
if(x&1) B=B*A;
}
int main(){
scanf("%lld%lld%lld",&n,&k,&mod);
C.n=n;C.m=2*n;A.n=n*2;A.m=n*2;
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
scanf("%lld",&C.F[i][j]);
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
A.F[i][j]=C.F[i][j];
for(int i=1;i<=n;i++)
for(int j=n+1;j<=n+n;j++)
if(i+n==j) //赋单位矩阵
A.F[i][j]=1; //相当于初始矩阵[1][2]的初值
for(int i=n+1;i<=n+n;i++)
for(int j=n+1;j<=n+n;j++)
if(i==j) //同单位矩阵
A.F[i][j]=1; //初始矩阵[2][2]的初值
ksm(k);
C=C*B;
for(int i=1;i<=n;i++)
{
for(int j=n+1;j<=n+n;j++)
printf("%lld ",C.F[i][j]); //输出[1][2]
printf("\n");
}
return 0;
}