基础知识
矩阵的概念
矩阵( (matrix) )是一个由数排列成的矩形,例如
是一个 (2 imes3) 的矩阵 (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 imes n) 矩阵,(Y) 是 (n imes p) 矩阵,那么 (Z) 是 (n imes 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 imes a^{-1}=a^{-1} imes a=1)。(可以用 (exgcd) 来计算)
同样,对于 (n imes n) 的矩阵,也存在一些特殊的矩阵 (A) 存在唯一的逆元 (A^{-1}) 使得 (A imes A^{-1}=A^{-1} imes A=I_{n}),其中 (I_{n}) 是 (n) 阶的单位矩阵。
矩阵快速幂
就是一个快速幂不过把之前的数变成了矩阵而已。
构造矩阵
讲的差不多了,讲下构造矩阵吧 (qwq)。
例题 (1):
先定义一个 (1 imes 2) 的矩阵
根据题意,显然,通过递推式,我们要得到一个 (1 imes 2) 的矩阵
然后,因为 (fib_{n}=fib_{n-1}+fib_{n-2}),所以转换为
设通过乘以一个 (2 imes 2) 的矩阵 (A)来实现,即
根据矩阵乘法,很容易构造出这个矩阵 (A)。
因为矩阵满足乘法结合律,所以
的第一个元素即为所求。
例题 (2):
跟例题1很类似,我们用同样的方法构造一个矩阵 (A)
先定义一个 (1 imes 3) 的矩阵
根据题意,显然,通过递推式,我们要得到一个 (1 imes 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) 项
其中(1leq n leq 2e^{9})
取模,所以不用考虑高精
模仿先前两个样例
先定义一个 (1 imes 3) 的矩阵
显然,通过递推式,我们要得到一个 (1 imes 3) 的矩阵
然后,因为 (f_{n}=f_{n-1}+f_{n-2}+1),所以转换为
于是就很容易构造出这个矩阵 (A)。
所以
的第一个元素即为所求。
例题4:
也是一道口胡的题
在例题1的基础上,再加
求 (s_{n}),其中 (1leq nleq 2e^{9})
取模,所以不用考虑高精
自己去推吧qwq
最后答案是
然后
最后,给出个结论,如果有 (f_n=p imes f_{n-1}+q imes f_{n-2}+r imes n+s),那么
补充:然后就能水道题了