# 矩阵快速幂小结

update in 9.17

## 矩阵

### 定义

$$A = \begin{bmatrix} a_{11} & a_{12} & \dots a_{1m} \\ a_{21}, & \dots & \dots \\ a_{31}, & \dots & \dots \\ a_{41} & \dots & a_{nm} \end{bmatrix}$$

### 运算

#### 加法

$$\begin{bmatrix} 1 & 1 & 2 \\ 1 & 0 & 1 \end{bmatrix} + \begin{bmatrix} 2 & 3 & 3 \\ 3 & 3 & 2 \end{bmatrix} = \begin{bmatrix} 3 & 4 & 5 \\ 4 & 3 & 3 \end{bmatrix}$$

$A + B = B + A$

$(A + B) + C = A + (B + C)$

### 乘法

$$\begin{bmatrix} 1 & 2\\ 2 & 3 \end{bmatrix} \times \begin{bmatrix} 2 & 4 & 5 \\ 3 & 4 & 3 \end{bmatrix} = \begin{bmatrix} 8 & 12 & 11 \\ 13 & 20 & 19 \end{bmatrix}$$

$(A \times B) \times C = A \times (B \times C)$

$(A + B) \times C = A \times C + B \times C$

$C(A + B) = C \times A + C \times B$

## 矩阵快速幂

#include<cstdio>
#define LL long long
using namespace std;
const int mod = 1e9 + 7;
int N;
LL K;
struct Matrix {
int m[101][101];
Matrix operator * (const Matrix &rhs) const {
Matrix ans = {};
for(int k = 1; k <= N; k++)
for(int i = 1; i <= N; i++)
for(int j = 1; j <= N; j++)
(ans.m[i][j] += 1ll * m[i][k] * rhs.m[k][j] % mod) %= mod;
return ans;
}
};
Matrix fastpow(Matrix a, LL p) {
Matrix base;
for(int i = 1; i <= N; i++) base.m[i][i] = 1;//构造单位矩阵
while(p) {
if(p & 1) base = base * a;
a = a * a; p >>= 1;
}
return base;
}
int main() {
scanf("%d %lld", &N, &K);
Matrix a;
for(int i = 1; i <= N; i++)
for(int j = 1; j <= N; j++)
scanf("%d", &a.m[i][j]);
a = fastpow(a, K);
for(int i = 1; i <= N; i++, puts(""))
for(int j = 1; j <= N; j++)
printf("%d ", a.m[i][j]);

return 0;
}

## 应用

### 斐波那契数列第$n$项

$$\begin{bmatrix} f_{n} \\ f_{n - 1} \end{bmatrix}$$

$$\begin{bmatrix} f_{n + 1} \\ f_{n} \end{bmatrix}$$

$$\begin{bmatrix} f_{n} + f_{n - 1} \\ f_{n} \end{bmatrix}$$

$$\begin{bmatrix} 1 & 1 \\ 1 & 0 \\ \end{bmatrix} \begin{bmatrix} f_{n} \\ f_{n - 1}\\ \end{bmatrix} = \begin{bmatrix} f_{n} + f_{n - 1} \\ f_{n}\\ \end{bmatrix}$$

// luogu-judger-enable-o2
#include<cstdio>
#include<cstring>
#define LL long long
using namespace std;
const int mod = 1e9 + 7;
LL K;
struct Matrix {
int m[101][101], N;
Matrix() {
memset(m, 0, sizeof(m));
N = 2;
}
Matrix operator * (const Matrix &rhs) const {
Matrix ans;
for(int k = 1; k <= N; k++)
for(int i = 1; i <= N; i++)
for(int j = 1; j <= N; j++)
(ans.m[i][j] += 1ll * m[i][k] * rhs.m[k][j] % mod) %= mod;
return ans;
}
};
Matrix fastpow(Matrix a, LL p) {
Matrix base;
for(int i = 1; i <= base.N; i++) base.m[i][i] = 1;//鏋勯€犲崟浣嶇煩闃?
while(p) {
if(p & 1) base = base * a;
a = a * a; p >>= 1;
}
return base;
}
int main() {
scanf("%lld", &K);
Matrix a;
a.m[1][1] = 1; a.m[1][2] = 1;
a.m[2][1] = 1; a.m[2][2] = 0;
a = fastpow(a, K - 1);
printf("%d", a.m[1][1]);
return 0;
}

### 路径计数问题

https://www.nowcoder.com/acm/contest/185/B

A是一个01矩阵 .
A[i][j]=1表示i号点和j号点之间有长度为1的边直接相连.

### 其他的常见矩阵推导

$$G_i = a\times G_{i - 1} + b\times G_{i - 2}$$

\begin{equation*}
\begin{bmatrix}
a&b\\
1 & 0\\
\end{bmatrix}^{i - 1}\times
\begin{bmatrix}
G_{1}\\
G_{0}\\
\end{bmatrix}=
\begin{bmatrix}
a&b\\
1 & 0\\
\end{bmatrix}\times
\begin{bmatrix}
G_{i - 1}\\
G_{i - 2}\\
\end{bmatrix}=
\begin{bmatrix}
G_{i}\\
G_{i - 1}\\
\end{bmatrix}
\end{equation*}

$$G_i = a\times G_{i - 1} + i^2$$

\begin{equation*}
\begin{bmatrix}
a&1&0&0\\
0 & 1&2&1\\
0 & 0&1&1\\
0 & 0&0&1\\
\end{bmatrix}^{i}\times
\begin{bmatrix}
G_{0}\\
1\\
1\\
1\\
\end{bmatrix}=
\begin{bmatrix}
a&1&0&0\\
0 & 1&2&1\\
0 & 0&1&1\\
0 & 0&0&1\\
\end{bmatrix}\times
\begin{bmatrix}
G_{i - 1}\\
i^2\\
i\\
1
\end{bmatrix}=
\begin{bmatrix}
G_{i}\\
(i + 1)^2\\
i + 1\\
1
\end{bmatrix}
\end{equation*}

$$G_i = a\times G_{i - 1} + i^3$$

\begin{equation*}
\begin{bmatrix}
a&1&0&0&0\\
0 & 1&3&3&1\\
0 & 0&1&2&1\\
0 & 0&0&1&1\\
0 & 0&0&0&1\\
\end{bmatrix}^{i}*
\begin{bmatrix}
G_{0}\\
1\\
1\\
1\\
1\\
\end{bmatrix}=
\begin{bmatrix}
a&1&0&0&0\\
0 & 1&3&3&1\\
0 & 0&1&2&1\\
0 & 0&0&1&1\\
0 & 0&0&0&1\\
\end{bmatrix}\times
\begin{bmatrix}
G_{i - 1}\\
i^3\\
i^2\\
i\\
1
\end{bmatrix}=
\begin{bmatrix}
G_{i}\\
(i + 1)^3\\
(i + 1)^2\\
i + 1\\
1
\end{bmatrix}
\end{equation*}

$$G_i = a\times G_{i - 1} + b^i$$

\begin{equation*}
\begin{bmatrix}
a&1\\
0 & b\\
\end{bmatrix}^{i}\times
\begin{bmatrix}
G_{0}\\
b\\
\end{bmatrix}=
\begin{bmatrix}
a&1\\
0 & b\\
\end{bmatrix}\times
\begin{bmatrix}
G_{i - 1}\\
b^{i}\\
\end{bmatrix}=
\begin{bmatrix}
G_{i}\\
b^{i+1}\\
\end{bmatrix}
\end{equation*}

## 参考资料

posted @ 2018-09-17 21:15  自为风月马前卒  阅读(627)  评论(0编辑  收藏  举报