>Link
luogu P3390
>Description
给定 N ∗ N N*N N∗N的矩阵 A A A,求 A k A^k Ak
>解题思路
矩阵乘法模板题
矩阵乘法:
定义
n
∗
q
n*q
n∗q 矩阵
A
A
A 和
q
∗
m
q*m
q∗m 矩阵
B
B
B,
A
∗
B
=
C
A*B=C
A∗B=C,得到
n
∗
m
n*m
n∗m 的矩阵
C
C
C
其中,
c
i
,
j
=
Σ
k
=
1
q
a
i
,
k
∗
b
k
,
j
c_{i,j}=Σ_{k=1}^{q}a_{i,k}*b_{k,j}
ci,j=Σk=1qai,k∗bk,j
由此看出,矩阵乘法支持结合律,不支持交换律
矩阵乘法快速幂直接 普通快速幂+矩阵乘法
>代码
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#define LL long long
using namespace std;
const LL p = 1e9 + 7;
struct matrix
{
int x, y;
LL a[110][110];
};
int n;
LL k;
matrix operator *(matrix a, matrix b) //重新定义乘法(矩阵)
{
matrix c;
c.x = a.x, c.y = b.y;
for (int i = 1; i <= c.x; i++)
for (int j = 1; j <= c.y; j++)
c.a[i][j] = 0;
for (int k = 1; k <= a.y; k++)
for (int i = 1; i <= a.x; i++)
for (int j = 1; j <= b.y; j++)
c.a[i][j] = (c.a[i][j] + a.a[i][k] * b.a[k][j] % p) % p;
return c;
}
matrix power (matrix A, LL k)
{
bool mark = 0;
matrix ret;
ret.x = ret.y = A.x;
for (; k; k >>= 1, A = A * A)
if (k & 1)
{
if (!mark)
{
for (int i = 1; i <= ret.x; i++)
for (int j = 1; j <= ret.y; j++)
ret.a[i][j] = A.a[i][j] % p;
mark = 1;
}
else ret = ret * A;
}
return ret;
}
int main()
{
scanf ("%d%lld", &n, &k);
matrix A, ans;
A.x = A.y = n;
for (int i = 1; i <= n; i++)
for (int j = 1; j <= n; j++)
scanf ("%lld", &A.a[i][j]);
ans = power (A, k);
for (int i = 1; i <= ans.x; i++)
{
for (int j = 1; j <= ans.y; j++)
printf ("%lld ", ans.a[i][j]);
printf ("\n");
}
return 0;
}