矩阵快速幂

【快速幂】

博客转载快速幂讲解

以下是我自己理解的快速幂(假设是求 a^{b}):

我们把 b 看成是 2 进制数,比如说 11 就是 1011,就是 2^0+2^1+2^3

那么 a^{11}=a^{2^0+2^1+2^3}=a^{2^0}\cdot a^{2^1}\cdot a^{2^3}

这样乘 11 次就直接降为了乘 3 次

时间复杂度O(log\, b

代码(求 a^{b}\, mod \, \, c):

#include<cstdio>
#include<cstring>
using namespace std;
int main()
{
	long long a,b,c,ans,res;
	scanf("%lld%lld%lld",&a,&b,&c);
	ans=1,res=a;
	while(b)
	{
		if(b&1)
		  ans=(ans*res)%c;
		res=(res*res)%c;
		b>>=1;
	}
	printf("%lld",ans);
	return 0;
}

 

【矩阵快速幂】

博客转载矩阵快速幂讲解

矩阵快速幂实际上和快速幂差不多

只不过是每次乘的时候改成矩阵乘法

下面的 res 和 ans 和上面的也差不多

具体的话我们以快速求斐波那契数列为例吧,例题传送门

.

上面是公式,我们只要只需要用矩阵快速幂就可以快速求解了

其实很多递推式(不只是斐波那契数列)都可以用矩阵快速幂快速求解,主要是推出原始矩阵的值,就比如斐波那契数列是 \begin{bmatrix} 1 & 1\\ 1 & 0 \end{bmatrix},不同的递推式的话就有不同的原始矩阵,推出来就可以很方便地求解了

#include<cstdio>
#include<cstring>
#include<algorithm>
#define N 10
#define mod 10000
using namespace std;
struct matrix
{
	int m[N][N];
}ans,res;
matrix multiply(matrix a,matrix b)
{
	int i,j,k;
	matrix temp;
	for(i=1;i<=2;++i)
	    for(j=1;j<=2;++j)
		temp.m[i][j]=0;
	for(i=1;i<=2;++i)
	    for(j=1;j<=2;++j)
		for(k=1;k<=2;++k)
		    temp.m[i][j]=(temp.m[i][j]+1ll*a.m[i][k]*b.m[k][j])%mod;
	return temp;
}
void quickpower(int x)
{
	int i,j;
	res.m[1][1]=1;ans.m[1][1]=1;
	res.m[1][2]=1;ans.m[1][2]=0;
	res.m[2][1]=1;ans.m[2][1]=0;
	res.m[2][2]=0;ans.m[2][2]=1;
	while(x)
	{
		if(x&1)
		    ans=multiply(ans,res);
		res=multiply(res,res);
		x>>=1;
	}
}
int main()
{
	int x;
	while(~scanf("%d",&x))
	{
		if(x==-1)  break;
		quickpower(x);
		printf("%d\n",ans.m[1][2]);
	}
	return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值