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
分析:
直接计算会超时 考虑矩阵
[
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为变换矩阵 那么可得
F
F
F为:
A
,
E
A,E
A,E
O
,
E
O,E
O,E
其中
E
E
E表示单位矩阵
O
O
O为全是
0
0
0的矩阵
注意初始矩阵构造要展开构造
S
S
S就在初始矩阵
[
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;
}