标签:存在 sse 元素 toc a* operator 目的 线性 play
按照一个长方阵列排列的复数或实数集合。
看不懂?那就看图
设\(A\)是一个\(n \times m\)的矩阵,则\(A\)可以表示为
\[
A_{n, m}=\left[\begin{array}{ll}A_{1,1}&A_{1,2}&\cdots &A_{1,m}\\A_{2,1}&A_{2,2}&\cdots &A_{2,m}\\\vdots&\vdots&\ddots&\vdots\\A_{n,1}&A_{n,2}&\cdots &A_{n,m}\end{array}\right]
\]
这\(m\times n\)个数成为矩阵\(A\)的元素,简称为元。数\(a_{i, j}\)位于矩阵\(A\)的第\(i\)行第\(j\)列,称为矩阵\(A\)的\((i, j)\)元。
\(m\times n\)矩阵可记作矩阵\(A\)或矩阵\(A_{m, n}\)
若矩阵\(A\)与矩阵\(B\)的行数和列数都相同,则称矩阵\(A\)与矩阵\(B\)是同型矩阵
实现:
const int N=100;
struct Matrix {
LL a[N][N]; int n, m;
Matrix(int type, int n, int m):n(n), m(m) {
memset(a, 0, sizeof(a));
}
void print() {
for (int i=0; i<n; i++, puts(""))
for (int j=0; j<m; j++)
printf("%d ", a[i][j]);
}
};
咕咕咕~
当且仅当矩阵\(A\)的列数等于矩阵\(B\)的行数时,\(A\times B\)有定义
不放设\(A\)是一个\(m\times n\)的矩阵,\(B\)是一个\(m\times p\)的矩阵,那么\(C=A\times B\)是一个\(n\times p\)的矩阵,且\(C_{i, j}=\sum_{k=1}^mA_{i, k}B_{k, j}\)
理解:\(C\)矩阵的\((i, j)\)元就是\(A\)矩阵中的第\(i\)行和\(B\)矩阵的第\(j\)列每项顺次相乘的和
更形象地理解,即为将\(A\)矩阵的第\(i\)行拿出来,顺时针旋转\(90^\circ\)后平移使其与\(B\)矩阵的第\(j\)列对齐,将每对对齐的数分别相乘再求和即可。
在后面矩阵快速幂的应用中有例子模拟。
实现:
Matrix operator*(const Matrix &a, const Matrix &b) {
assert(a.m==b.n);
Matrix c(0, a.n, b.m);
for (int i=0; i<a.n; i++)
for (int j=0; j<b.m; j++)
for (int k=0; k<a.m; k++)
c.a[i][j]=(c.a[i][j]+a.a[i][k]*b.a[k][j])%P;
return c;
}
根据矩阵乘法的定义,一个\(n\times n\)的矩阵显然可以进行幂运算。
要求在\(O(\log n)\)时间内求出一个矩阵的\(n\)次幂
对于整数,我们可以将指数二进制拆分后快速幂。
那么对于矩阵是否可以进行类似的操作呢?
显然可以。
实现矩阵乘法后,运算部分与快速幂无异。
注意快速幂要将答案的初值赋为\(1\),目的是使\(ans\times x=x\),避免在乘法时对\(ans\)讨论。那么是否也存在一个矩阵满足类似的性质呢?
确实存在。
对于任意一个\(n\times n\)的矩阵\(x\),存在\(n\times n\)的单位矩阵\(I\),满足\(I\times x=x\)。
很容易得到这个矩阵为
\[
I=\left[\begin{array}{ll}1&0&0&\cdots&0\\0&1&0&\cdots&0\\0&0&1&\cdots&0\\\vdots&\vdots&\vdots&\ddots&\vdots\\0&0&0&\cdots&1\end{array}\right]
\]
Matrix qpow(Matrix a, int b) {
assert(a.n==a.m);
Matrix ans(1, a.n, a.m);
for (; b; b>>=1, a=a*a) if (b&1) ans=ans*a;
return ans;
}
以洛谷模板题洛谷P1939 【模板】矩阵加速(数列)为例
此题\(f_n=f_{n-1}+f_{n-3}\)
用矩阵改写转移
\[
\left[\begin{array}{ll}f_n\\f_{n-1}\\f_{n-2}\\f_{n-3}\end{array}\right]=\left[\begin{array}{ll}1&0&1&0\\1&0&0&0\\0&1&0&0\\0&0&1&0\end{array}\right]\times\left[\begin{array}{ll}f_{n-1}\\f_{n-2}\\f_{n-3}\\f_{n-4}\end{array}\right]
\]
可以验证此矩阵转移式和题中线性递推式等价。
我们上面矩阵乘法讲的trick来验证一下答案矩阵的第一行,即\(f_n\)。
右边第一个矩阵的第一行顺时针旋转\(90^\circ\)并平移使其与和第二个矩阵的第一列对齐
\[
\left[\begin{array}{ll}1\\0\\1\\0\end{array}\right]\left[\begin{array}{ll}f_{n-1}\\f_{n-2}\\f_{n-3}\\f_{n-4}\end{array}\right]
\]
将每对对齐的数相乘得
\[
\left[\begin{array}{ll}1\times f_{n-1}\\0\times f_{n-2}\\1\times f_{n-3}\\0\times f_{n-4}\end{array}\right]
\]
求和,应用递推式得
\[
f_{n-1}+f_{n-3}=f_n
\]
答案矩阵后三行很容易验证。那么等式成立
将这个等式迭代下去得
\[
\left[\begin{array}{ll}f_n\\f_{n-1}\\f_{n-2}\\f_{n-3}\end{array}\right]=\left[\begin{array}{ll}1&0&1&0\\1&0&0&0\\0&1&0&0\\0&0&1&0\end{array}\right]^{n-4}\times\left[\begin{array}{ll}f_1\\f_2\\f_3\\f_4\end{array}\right]
\]
\(f_1\)到\(f_4\)均已知,那么利用矩阵快速幂即可在\(O(\log n)\)时间内求出\(f\)数列的第\(n\)项
标签:存在 sse 元素 toc a* operator 目的 线性 play
原文地址:https://www.cnblogs.com/LiHaozhe/p/11755059.html