线性递推公式的矩阵快速幂技巧
快速幂
顾名思义, 快速幂是指快速求解幂运算的技巧。 正常求
以求
快速幂的核心代码如下:
/**
* 求 x^n 的值且结果对mod取余
*/
public static int power(int x, int n, int mod) {
long res = 1, a = x;// 临时变量用long类型防止乘积超出整形范围
while (n > 0) {
if ((n & 1) == 1) {
res = (res * a) % mod;
}
a = (a * a) % mod;
n >>= 1;
}
return (int) res;
}
矩阵乘法
按记忆里的内容简单说一下矩阵和矩阵乘法的概念, 有表述不严谨的地方请自行参考线性代数相关知识。
简单通俗来说, 矩阵就是m行n列的一组数字, 比如
当矩阵A的列数与矩阵B的行数相等时, A和B相乘才有意义。 乘积矩阵i行j列的值由矩阵A的i行与B的j列值依次相乘再累加得到, 即
设
用二维数组来表示矩阵, 下面是矩阵相乘的核心代码:
/**
* 矩阵A和B的乘积, 结果对mod取余
* A的列数必须等于B的行数
*/
public static int[][] matrixMultiply(int[][] a, int[][] b, int mod) {
int m = a.length, n = b[0].length;
int k = b.length;
int[][] res = new int[m][n];
for (int aRow = 0; aRow < a.length; aRow++) {
for (int bCol = 0; bCol < n; bCol++) {
long num = 0;
for (int i = 0; i < k; i++) {
num = (num + (long) a[aRow][i] * b[i][bCol]) % mod;
}
res[aRow][bCol] = (int) num;
}
}
return res;
}
矩阵快速幂
只有行列数相同的方形矩阵才能求幂, 矩阵的幂运算可以用相同技巧来快速求解。 这里再介绍一个单位矩阵 I 的概念, 简单说就是主对角线上值为1其它位置全部为0的方形矩阵, 任何矩阵与单位矩阵的乘积都不会改变, 等同于自然数中的1。
代码如下:
/**
* 求矩阵A的n次幂, 矩阵值对mod取余
*/
public static int[][] matrixPower(int[][] a, int n, int mod) {
int row = a.length;
// res初始化为单位矩阵
int[][] res = new int[row][row];
for (int i = 0; i < row; i++) {
res[i][i] = 1;
}
while (n > 0) {
if ((n & 1) == 1) {
res = matrixMultiply(a, res, mod);
}
a = matrixMultiply(a, a, mod);
n >>= 1;
}
return res;
}
应用场景
- 固定关系线性递推的1维k阶问题快速求第i项, 比如斐波那契数、泰波那契数等;
- 线性递推的k维1阶问题快速求第i项, 比如统计元音字母序列的数目、学生出勤记录II等;
相关题目
本文表述基于作者主观理解,如有错漏或歧义之处,欢迎评论指出沟通交流
分类:
Algorithm
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)