矩阵&矩阵加速学习笔记

· · 算法·理论

什么是矩阵:

简单来说,矩阵是一个按照矩形排列的数表,由行(\text{row})和列(\text{column})组成,用于表示数据、方程、线性变换等。

常见类型的矩阵:

矩阵的常见操作:

const int N=5;
void add(int a[][N],int b[][N],int c[][N]){
//矩阵a和b进行加法,结果保留在c中
  static int t[N][N];
  memset(t,0,sizeof t);
  for(int i=1;i<N;i++){
    for(int j=1;j<N;j++){
      t[i][j]+=a[i][j]+b[i][j];
    }
  }
  memcpy(c,t,sizeof t);
}
const int N=5;
void zhuan_zhi(int a[][N],int b[][N]){
//矩阵a进行转制,结果保留在b中
  static int t[N][N];
  memset(t,0,sizeof t);
  for(int i=1;i<N;i++){
    for(int j=1;j<N;j++){
      t[j][i]=a[i][j];
    }
  }
  memcpy(b,t,sizeof t);
}

::::info[矩阵乘法过程模拟]{open} ::::

有的人可能就会问了,作者作者,矩阵在 \texttt{C++} 中也没有啥用啊,让我白看这么久。

其实,你说错了,有一个黑科技,他就是矩阵加速!让算法飞起来的数学魔法!

矩阵加速的定义

矩阵加速是一种利用矩阵快速幂来优化线性递推问题时间复杂度的重要方法,能将许多 O(n) 时间复杂度的递推问题优化到 O(\log n)

转移矩阵的构建

基本原理

对于形如 f(n) = a_1 \cdot f(n-1) + a_2 \cdot f(n-2) + ... + a_k \cdot f(n-k) 的线性递推关系,我们可以将其转化为矩阵幂运算的形式:

\begin{bmatrix} f(n) \\ f(n-1) \\ f(n-2) \\ \vdots \\ f(n-k+1) \end{bmatrix} = \begin{bmatrix} a_1 & a_2 & a_3 & \cdots & a_k \\ 1 & 0 & 0 & \cdots & 0 \\ 0 & 1 & 0 & \cdots & 0 \\ \vdots & \vdots & \ddots & \ddots & \vdots \\ 0 & 0 & \cdots & 1 & 0 \end{bmatrix} \begin{bmatrix} f(n-1) \\ f(n-2) \\ f(n-3) \\ \vdots \\ f(n-k) \end{bmatrix}

::::success[解释] 对于第一行,f(n) = a_1 \times f(n-1) + a_2 \times f(n-2) + \cdots + a_k \times f(n-k)

对于后面几行,f(i)=f(i)

示例(斐波那契数列):

\begin{bmatrix} 1 & 1 \\ 1 & 0 \end{bmatrix}

第一行:f(n) = 1*f(n-1) + 1*f(n-2)

第二行:保持 f(n-1)

结果矩阵的初始化:

  1. 单位矩阵

    • 对角线为 1,其余为 0
  2. 初始状态向量

    • 包含已知的前 k 项值。

例题讲解

P1939

转移矩阵

首先明确想要的矩阵,

\begin{bmatrix} f(n) \\ f(n-1) \\ f(n-2) \\ \end{bmatrix}

和转移过来的矩阵,

\begin{bmatrix} f(n-1) \\ f(n-2) \\ f(n-3) \\ \end{bmatrix}

构建式子

\begin{bmatrix} f(n) \\ f(n-1) \\ f(n-2) \\ \end{bmatrix} = \begin{bmatrix} A & B & C \\ D & E & F \\ G & H & I \\ \end{bmatrix} \begin{bmatrix} f(n-1) \\ f(n-2) \\ f(n-3) \\ \end{bmatrix}

根据 f(n)=f(n-1)+f(n-3),解出 A=1,B=0,C=1

其余的根据 f(i)=f(i) 解出 D=1,E=0,F=0,G=0,H=1,I=0。然后转移矩阵就构建好了。

初始矩阵

因为

\begin{bmatrix} f(n) \\ f(n-1) \\ f(n-2) \\ \end{bmatrix} = \begin{bmatrix} 1 & 0 & 1 \\ 1 & 0 & 0 \\ 0 & 1 & 0 \\ \end{bmatrix} ^{n-3} \begin{bmatrix} f(3) \\ f(2) \\ f(1) \\ \end{bmatrix}

所以初始矩阵为 \begin{bmatrix} f(3) \\ f(2) \\ f(1) \\ \end{bmatrix}

代码点这。

::::warning[注意] 矩阵乘的时候矩阵的顺序别填反了。 ::::

::::success[题单链接] https://www.luogu.com.cn/training/1074066 ::::