矩阵快速幂

本文深入讲解矩阵快速幂的原理及应用,从矩阵的基本运算出发,详细介绍矩阵乘法及其在快速幂算法中的应用。通过实例说明如何将递推公式转化为矩阵形式,以便利用矩阵快速幂求解复杂问题。

 矩阵快速幂类似于快速幂,如果不懂快速幂的可以看一下我的这个博客:快速幂

 多了“矩阵”二字好像变得高大上,其实懂一点矩阵性质的人就觉得这好小儿科了。

先来说说矩阵的性质吧:

如图,一个m*n的矩阵A和m*n的矩阵B:

矩阵加法(这个可以忽略)

矩阵乘法(敲重点)

  1. A*B=C(一个m*n的矩阵)

以上中,矩阵快速幂有两个需要理解的,分别是矩阵乘法中的1和2.c

1显而易见,2.c是因为如:  A的n次方  (A*A)*A*A*A*A........=(A)*(A*A)*(A*A*A*A)*(A*........而不影响。

思路由于和快速幂思路相同,所以直接代码(见矩阵快速幂模板题poj 3070 ):

f(n)=f(n-1)+f(n-2)等价于(这张盗的图)

需要的结构体:

struct matrix
{
	ll m[3][3];
}ans;

m*n的矩阵A和m*n的矩阵B相乘:【这个函数可以重写,可以改成随便什么几乘以几*随便什么几乘以几的,这个得自己想想,因题而异】

matrix matrixmultiply(matrix a,matrix b,ll n)
{
	matrix c;
	for(int i=1;i<=n;i++)
		for(int j=1;j<=n;j++)
		c.m[i][j]=0;
	for(int i=1;i<=n;i++)
		for(int j=1;j<=n;j++)
			for(int k=1;k<=n;k++)
			{
				c.m[i][j]+=(a.m[i][k]*b.m[k][j])%mod;
			}
	return c;
}

矩阵快速幂主要函数实现(类快速幂的实现):

ll quickpow(matrix a,ll n)
{
	for(int i=1;i<=2;i++)
		for(int j=1;j<=2;j++)
		{
			if(i==j) ans.m[i][j]=1;
			else ans.m[i][j]=0;
		}
	while(n)
	{
		if(n&1) ans=matrixmultiply(ans,a,2);
		a=matrixmultiply(a,a,2);
		n>>=1;
	}
	return ans.m[1][2];
}

主函数部分:

int main()
{
	ll n;
	while(cin>>n&&(n!=-1))
	{
		matrix a;
		a.m[1][1]=a.m[1][2]=a.m[2][1]=1;
		a.m[2][2]=0;
		ll ans=0;
		quickpow(a,n);
		cout<<quickpow(a,n)%mod<<endl;;
	}
	return 0;
}

说一句大实话:上面的依旧是基础篇,也就是说,给好的矩阵让你算。这个矩阵——进阶让我们来感受一下表达式变矩阵来计算吧!

顺便解释一下1973192-ec47f255c4d6d9a4.png (1000×319)这个图,其实左边那个是1*n的(也就是躺着一排的),最右边的也是一样的,否则无法进行矩阵乘法(看了半天 ╥﹏╥...),这样写可能只是为了好看吧。中间的状态转移矩阵每一行的各个系数讨到左边的矩阵中即可。

弄一个超好理解的图,乘号上面的那个矩阵就是每个变量,下面7*7的每行是对应的系数,等号右边对应每行的是每个得到的值,相对应而已。只是为了方便求中间那个状态转移矩阵(这样直接填7*7的矩阵就行)。

还有还有,推f(n-1)的也行,自行脑补。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值