基础矩阵学习笔记
基础知识
矩阵的概念
矩阵( \(matrix\) )是一个由数排列成的矩形,例如
是一个 \(2\times3\) 的矩阵 \(A=(a_{i,j})\)。其中 \(i=1,2\),\(j=1,2,3\)。第 \(i\) 行第 \(j\) 列的元素用 \(a_{i,j}\) 表示。
由此,可以开一个结构体 \(Matrix\),并作初始化。
struct Matrix
{
int a[N][N];
Matrix()
{
memset(a,0,sizeof a);
}
}a,ans;
矩阵的运算
加法和减法就是每个对应的元素加或减。但是注意,两个矩阵行数、列数要相等。
Matrix operator +(const Matrix x)
{
Matrix z;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
z.a[i][j]=(a[i][j]+x.a[i][j])%mod;
}
}
return z;
}
乘法比较复杂 \(qwq\)。有两个矩阵 \(Z\) 和 \(Y\)。当 \(Z\) 的列数等于 \(Y\) 的行数时,定义一个矩阵 \(Z\),可得 \(Z=XY\)。如果 \(X\) 是 \(m\times n\) 矩阵,\(Y\) 是 \(n\times p\) 矩阵,那么 \(Z\) 是 \(n\times p\) 矩阵。
其中 \(Z_{i,j}\) 满足
根据这个定义容易得到 \(O(n^3)\) 的矩阵乘法,由于作者很逊,所以不会复杂度更优秀的做法。
Matrix operator *(const Matrix x)
{
Matrix z;
for(int i=1;i<=n;i++)
{
for(int k=1;k<=n;k++)//据说k写在第二层循环会快一点?
{
for(int j=1;j<=n;j++)
{
z.a[i][j]=(z.a[i][j]+a[i][k]*x.a[k][j])%mod;
}
}
}
return z;
}
对了,矩阵乘法还有个性质,就是矩阵乘法也是满足乘法结合律的,这对接下来很有帮助。
逆矩阵
在取模下,每个元素 \(a\) 都有唯一的逆元 \(a^{-1}\) 使得 \(a\times a^{-1}=a^{-1}\times a=1\)。(可以用 \(exgcd\) 来计算)
同样,对于 \(n\times n\) 的矩阵,也存在一些特殊的矩阵 \(A\) 存在唯一的逆元 \(A^{-1}\) 使得 \(A\times A^{-1}=A^{-1}\times A=I_{n}\),其中 \(I_{n}\) 是 \(n\) 阶的单位矩阵。
矩阵快速幂
就是一个快速幂不过把之前的数变成了矩阵而已。
构造矩阵
讲的差不多了,讲下构造矩阵吧 \(qwq\)。
例题 \(1\):
先定义一个 \(1\times 2\) 的矩阵
根据题意,显然,通过递推式,我们要得到一个 \(1\times 2\) 的矩阵
然后,因为 \(fib_{n}=fib_{n-1}+fib_{n-2}\),所以转换为
设通过乘以一个 \(2\times 2\) 的矩阵 \(A\)来实现,即
根据矩阵乘法,很容易构造出这个矩阵 \(A\)。
因为矩阵满足乘法结合律,所以
的第一个元素即为所求。
例题 \(2\):
跟例题1很类似,我们用同样的方法构造一个矩阵 \(A\)
先定义一个 \(1\times 3\) 的矩阵
根据题意,显然,通过递推式,我们要得到一个 \(1\times 3\) 的矩阵
然后,因为 \(fib_{n}=fib_{n-1}+fib_{n-3}\),所以转换为
于是就很容易构造出这个矩阵 \(A\)。
所以
的第一个元素即为所求。
例题 \(3\):
题目是我自己口胡的
求数列
\(f_n=f_{n-1}+f_{n-2}+1,f_{1}=f_{2}=1\)的第 \(n\) 项
其中\(1\leq n \leq 2e^{9}\)
取模,所以不用考虑高精
模仿先前两个样例
先定义一个 \(1\times 3\) 的矩阵
显然,通过递推式,我们要得到一个 \(1\times 3\) 的矩阵
然后,因为 \(f_{n}=f_{n-1}+f_{n-2}+1\),所以转换为
于是就很容易构造出这个矩阵 \(A\)。
所以
的第一个元素即为所求。
例题4:
也是一道口胡的题
在例题1的基础上,再加
求 \(s_{n}\),其中 \(1\leq n\leq 2e^{9}\)
取模,所以不用考虑高精
自己去推吧qwq
最后答案是
然后
最后,给出个结论,如果有 \(f_n=p\times f_{n-1}+q\times f_{n-2}+r\times n+s\),那么
补充:然后就能水道题了