矩阵快速幂

在一些递推n很大的时候,很可能会超时,这样矩阵快速幂就派上用场了.

下面看一个非常经典的例题,斐波那契数列
                   已知f[1]=1,f[2]=1;F[n]=f[n-1]+f[n-2],给定n,求f[n];
一看到这到题很多人就会说这不是到入门题吗?;直接上代码


#include<cstdio>
#include<cstdlib>
#include<iostream>
using namespace std;
int main() {
	long long n,a,b;
	scanf("%lld",&n);
	a=1,b=1;
	for(int i=3; i<=n; i++)
		b=a+b,a=b-a;
	printf("%lld",b);
	return 0;
}

但是这样很明显是初学者的想的.如果n大一点你呢?这样子这个算法就有点显得太垃圾了.所以我们应该另一种更优的算法.那么这个算法是什么呢?这就要用的了矩阵快速幂了.那么什么是矩阵快速幂呢?在介绍快速幂之前,有几个前置技能

  • 学过oi
  • 会打程序
  • 快速幂
  • 矩阵乘法

前面两个默认你已经掌握了,如果没有,请按Alt + F4 即可;
首先讲一讲快速幂:

什么是快速幂呢?快速幂顾名思义就是快速求幂.其时间复杂度为 O(log₂N), 与朴素的O(N)相比效率有了极大的提高.
如果不想学可以用朴素算法,但是超时就不管了
           快速幂算法的详解:传送门

接下来讲一讲矩阵乘法
矩阵相乘最重要的方法是一般矩阵乘积.它只有在第一个矩阵的列数和第二个矩阵的行数相同时才有意义.一般单指矩阵乘积时,指的便是一般矩阵乘积.一个m×n的矩阵就是m×n个数排成m行n列的一个数阵。由于它把许多数据紧凑的集中到了一起,所以有时候可以简便地表示一些复杂的模型.
上面为百度百科,不想看或看不懂都可以自动忽略.

那么到底什么是矩阵乘法呢?矩阵乘法其实就是矩阵相乘

这个算式看不懂对不对,没事来举个例子

这样就很好理解了吧

那么接下来就开始讲矩阵快速密了,其实这个很简单,就是讲矩阵乘法和快速幂,这个就不怎讲了,是自己码代码的能力了,接下来直接上代码

#include<cstdio>
#include<cstdlib>
#include<iostream>
using namespace std;
const int mod=1e9+7;
long long  n,k;
struct node {
	long long a[101][101];
} ans,res;
node ksm(node x,node y) {
	node l;
	for(long long i=1; i<=3; i++)
		for(long long j=1; j<=3; j++) {
			l.a[i][j]=0;
			for(long long k=1; k<=3; k++)
				l.a[i][j]+=x.a[i][k]*y.a[k][j],l.a[i][j]%=mod;
		}
	return l;
}
int main() {
	scanf("%lld",&k);
	k-=1;
	ans.a[1][1]=ans.a[2][2]=res.a[1][1]=res.a[1][2]=res.a[2][1]=1;
	while(k) {
		if(k&1)
			ans=ksm(ans,res);
		res=ksm(res,res);
		k>>=1;
	}
	printf("%d\n",ans.a[1][1]);
	return 0;
}

end

posted @ 2018-08-14 11:57  撤云  阅读(256)  评论(0编辑  收藏  举报
……