题解:P1962 斐波那契数列
a202401006 · · 题解
题目传送门
解析
题目大意
求斐波那契数列的
考察知识
本题考查矩阵乘法、快速幂、数学。
思路
看一眼题目,发现底部有这么一句话;对于
题目的标签提醒了一下:数学、递推、矩阵运算和矩阵乘法。
的确,这一题要用矩阵快速幂去做。
:::info[矩阵快速幂] 首先了解一下什么是矩阵快速幂。有需要的可以前往矩阵快速幂的模板题进行学习,这里简单地讲一下。
矩阵快速幂指的就是一个矩阵的若干次方的结果,矩阵怎么进行幂运算?很简单,也就是若干个原来的矩阵相乘。举个例子:假设有一个矩阵
没看懂?文字解释就是:结果矩阵
至于快速幂,这里就不讲了,如有需要可以前往快速幂的模板题。 :::
相信大家都知道斐波那契数列,题目里面也有。这一题虽然使用矩阵快速幂进行优化,但是不变的仍然是那条斐波那契数列的公式
要想让
也就是说,
由于
代码
//998244353
#include<bits/stdc++.h>
#define int long long
#define itn int
using namespace std;
const int MOD=1e9+7;
int n;
struct node
{
int matrix[5][5];
node(){memset(matrix,0,sizeof(matrix));};
}A,C;
inline node operator*(node x,node y)
{
node t;
for(int i=1;i<=2;i++)
{
for(itn j=1;j<=2;j++)
{
for(int k=1;k<=2;k++)
{
t.matrix[i][j]=(t.matrix[i][j]+x.matrix[i][k]*y.matrix[k][j])%MOD;
}
}
}
return t;
}
inline void quickpow(int k)
{
while(k)
{
if(k%2)
{
A=A*C;//注意千万不要弄反了,必须是A*C而不是C*A,否则就会发现,原本一直都应该只有一行的矩阵A变成了两行
}
k/=2;
C=C*C;
}
}
signed main()
{
cin>>n;
if(n<=2)
{
cout<<1;
return 0;
}
A.matrix[1][1]=1;
A.matrix[1][2]=1;
C.matrix[1][1]=1;
C.matrix[1][2]=1;
C.matrix[2][1]=1;
C.matrix[2][2]=0;
quickpow(n-2);
cout<<A.matrix[1][1]%MOD;
}