在一些递推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
来源:https://www.cnblogs.com/hbxblog/p/9473773.html