矩阵加速递推与转移矩阵构造方法
一.前置芝士
1.矩阵乘法
最一般的矩阵乘法是一个
用公式表达就是
代码就直接模拟
貌似有时间复杂度为
但貌似除了用来卡常并没有什么用
inline void mul(int A[N][P], int B[P][M], int C[N][M]){
for(int i = 1; i <= N; i++)
for(int j = 1; j <= M; j++)
for(int k = 1; k <= P; k++)
C[i][j] += A[i][k] * B[k][j];
}
2.矩阵快速幂
求一个矩阵的
这是一个求
inline int fast_power(int a, int b, int p){
int ret = 1;
while(b){
if(b & 1) ret = (ret * a) % p;
a = (a * a) % p;
b >>= 1;
}
return ret;
}
那么对于一个矩阵求快速幂只要把上面的代码魔改一通就好了。
首先代码中的
考虑如下的一个方阵
随便找几个矩阵和它相乘(如果能的话),会发现与它相乘的矩阵还是那个矩阵,没有变,所以这个矩阵就相当于 “
把上面的两个代码结合起来就好了。代码就不放了
二.矩阵加速
1.基本原理
拿斐波那契数列来举例子
现在要求这个序列的第
我们把
然后我们就需要最重要的东西——转移矩阵了。
如果我们构造一个矩阵
那么我们就可以一直乘上
但我们只要求第
2.转移矩阵的构造方法
乱搞
常规型
非常简单,每一项只跟前几项有关系。
先放一个矩阵加速入门题。
根据题目给的递推式,我们很容易可以列出递推的矩阵。(就是上面的矩阵
这个矩阵中
现在来推矩阵
已知
所以这个新矩阵可以改成
根据矩阵乘法的公式可知
然后根据上面的式子可以凑出转移方程
其实还是很好凑的
找找规律,可以得出一条算阶上的结论
如果原矩阵的第
含常数型
类似于这样的递推式
把它塞到一个矩阵
乘上转移矩阵
发现常数项根本没变,就在原来的位置所以矩阵
所以这种形式的递推式常数直接搬到下一个矩阵就好了。
转移矩阵就是
总结一下,这种带常数的递推式直接把常数放到矩阵里,转移的时候直接搬到下一个矩阵就行了。
含未知数型
类似与这样的形式
这个时候有点麻烦,不仅要推
这种情况中递推矩阵要同时递推
要把
原式变成了这个样子
先推
那么这个递推式就是一个很简单的含常数型递推式,容易得出递推矩阵和转移矩阵
递推矩阵:
转移矩阵:
其实这两个矩阵做题时不用构造
现在构造
乘上转移矩阵之后应该是这个样子的
上面四句话“翻译”一下
新矩阵第
新矩阵第
新矩阵第
新矩阵第
之前说过
如果原矩阵的第
这句话改一下
如果新矩阵的第
再根据上面翻译的四句话,很容易写出转移矩阵
遇到难推的矩阵,可以用上面的方法去想。
再放一个比较难的递推式
和上面一样,设
这要递推
我们知道
所以
那么要推出
这个
递推矩阵是
乘上转移矩阵后应得到
用之前的方法,转移矩阵也很好构造,注意
转移时,
貌似矩阵还能转移带 但本蒟蒻不会。就先放着
参考资料
算法竞赛进阶指南
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
· 为什么 退出登录 或 修改密码 无法使 token 失效