矩阵乘法&矩阵快速幂

本文介绍如何使用矩阵快速幂方法优化斐波那契数列及广义斐波那契数列的计算,并提供了一段C++代码示例来求解广义斐波那契数列中某项除以特定数后的余数。

刚好在复习dp,顺便把矩阵快速幂加速递推给复习了。

首先矩阵乘法:f[i][j]=\sum_{k=1}^{sizeA[][K]/sizeB[K][]}A[i][k]*B[k][j]

我们观察斐波那契数列f[n]=f[n-1]+f[n-2],我们构造矩阵乘法

A:[ fn-2 fn-1]

B:[0 1]

    [1 1]

C=A*B=[fn-1 fn-2+fn-1]=[fn-1 fn]

所以对于C[fn-1 fn],不难得出C=[f1 f2]*B^(n-2),而B是预先设置好的矩阵,于是就可以用上矩阵快速幂。

栗一、广义斐波那契数列

Description

广义的斐波那契数列是指形如a(n)=p*a(n-1)+q*a(n-2)的数列。今给定数列的两系数p和q,以及数列的最前两项a(1)和a(2),另给出两个整数n和m,试求数列的第n项a(n)除以m的余数。

Input

输入包含一行6个整数。依次是p,q,a(1),a(2),n,m,其中在p,q,a(1),a(2)整数范围内,n和m在长整数范围内。

Output

输出包含一行一个整数,即a(n)除以m的余数。

Sample Input

1 1 1 1 10 7

Sample Output

6

【样例说明】 数列第10项是55,除以7的余数为6。

#include<bits/stdc++.h>
using namespace std;
#define Inc(i,L,r) for(register int i=(L);i<=(r);++i)
#define Red(i,r,L) for(register int i=(r);i>=(L);--i)
#define int long long
int p,q,n,m,f1,f2;
struct Martix{
	int a[10][10];
	inline void init(bool flag){//可构造单位矩阵 
		memset(a,0,sizeof(a));
		if(flag)Inc(i,1,4)a[i][i]=1;
	}
};
inline Martix mul(Martix a,Martix b,int I,int J,int K,int Mod){
	Martix ans;
	ans.init(0);
	Inc(i,1,I)Inc(j,1,J)Inc(k,1,K)(ans.a[i][j]+=(a.a[i][k]*b.a[k][j]))%=Mod;
	return ans;
}
inline int quick_pow(int lm,int Mod){
	Martix a;
	a.a[1][1]=0;
	a.a[1][2]=q;
	a.a[2][1]=1;
	a.a[2][2]=p;//构造矩阵A 
	Martix ans;
	ans.init(1);
	while(lm){
		if(lm&1)ans=mul(ans,a,2,2,2,Mod);
		a=mul(a,a,2,2,2,Mod);
		lm>>=1;
	}
	return (ans.a[1][2]*f1+ans.a[2][2]*f2)%Mod;
}
signed main(){
	scanf("%lld%lld%lld%lld%lld%lld",&p,&q,&f1,&f2,&n,&m);
	if(n==1)cout<<f1%m<<"\n";
	else if(n==2)cout<<f2%m<<"\n";
	else cout<<quick_pow(n-2,m)<<"\n";
	return 0;
}

栗二、连分数

有时间再写吧~

### 矩阵乘法的实现 在C++中,矩阵乘法可以通过自定义的数据结构和运算符重载来实现。首先定义一个`Matrix`结构体,其中包含一个二维数组用于存储矩阵元素,并通过运算符重载实现矩阵乘法操作。矩阵乘法的时间复杂度为 $ O(n^3) $,这是由于三重循环嵌套导致的[^3]。以下是矩阵乘法的具体实现: ```cpp struct Matrix { int m[101][101]; // 假设矩阵最大为100x100 Matrix() { memset(m, 0, sizeof(m)); // 初始化矩阵为0 } }; Matrix operator*(const Matrix &amp;x, const Matrix &amp;y) { Matrix ret; for (int i = 1; i &lt;= n; i++) { // n为矩阵的大小 for (int j = 1; j &lt;= n; j++) { for (int k = 1; k &lt;= n; k++) { ret.m[i][j] = (ret.m[i][j] + (x.m[i][k] * y.m[k][j]) % MOD) % MOD; // MOD用于取模,防止溢出 } } } return ret; } ``` ### 矩阵快速幂算法的实现 矩阵快速幂算法是快速幂算法在矩阵上的扩展。与普通快速幂初始化`ans`为1类似,矩阵快速幂将`ans`初始化为单位矩阵,其作用等同于1,任何矩阵乘以单位矩阵都等于原矩阵[^4]。矩阵快速幂的时间复杂度主要取决于矩阵乘法的时间复杂度,即 $ O(n^3) $,但由于幂运算的对数时间复杂度,整体效率较高[^1]。以下是矩阵快速幂的具体实现: ```cpp Matrix MatrixQuickPower(const Matrix &amp;A, int k) { Matrix res; for (int i = 1; i &lt;= n; i++) { res.m[i][i] = 1; // 初始化res为单位矩阵 } while (k) { if (k &amp; 1) { res = res * A; // 如果当前位为1,乘上当前的A } A = A * A; // A平方 k &gt;&gt;= 1; // 右移一位 } return res; } ``` ### 应用示例:斐波那契数列 矩阵快速幂的一个典型应用是求解斐波那契数列。通过构造一个转移矩阵 $ A = \begin{bmatrix} 0 &amp; 1 \\ 1 &amp; 1 \end{bmatrix} $,可以将斐波那契数列递推公式转化为矩阵乘法形式。初始矩阵为 $ [a_1, a_2] $,通过矩阵快速幂可以高效地计算出第 $ n $ 项[^5]。 ```cpp Matrix fibMatrix = {{0, 1}, {1, 1}}; // 构造转移矩阵 Matrix result = MatrixQuickPower(fibMatrix, n - 1); // 计算矩阵的n-1次幂 int fib_n = (result.m[1][1] * a1 + result.m[1][2] * a2) % MOD; // 计算第n项斐波那契数 ``` ### 总结 矩阵乘法矩阵快速幂是解决线性递推问题的重要工具。通过矩阵快速幂算法,可以将递推问题的时间复杂度从指数级降低到对数级,从而显著提高计算效率。在C++中,通过结构体和运算符重载可以方便地实现矩阵乘法矩阵快速幂算法。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值