裴波拉契数列II
题目链接:裴波拉契数列II
~~~~~~~~~~~~~~~~~ 裴波拉契数列
解题思路
我们设两个个数列,分别为:
∣ f [ n − 2 ] f [ n − 1 ] ∣ \begin{vmatrix}f[n-2]&f[n-1]\end{vmatrix} ∣∣f[n−2]f[n−1]∣∣
∣ 0 1 1 1 ∣ \begin{vmatrix}0 & 1\\1 &1\end{vmatrix} ∣∣∣∣0111∣∣∣∣
将他们相乘,得:
∣ f [ n − 1 ] f [ n − 2 ] + f [ n − 1 ] ∣ \begin{vmatrix}f[n-1]&f[n-2]+f[n-1]\end{vmatrix} ∣∣f[n−1]f[n−2]+f[n−1]∣∣
即
∣ f [ n − 1 ] f [ n ] ∣ \begin{vmatrix}f[n-1]&f[n]\end{vmatrix} ∣∣f[n−1]f[n]∣∣
根据矩阵乘法的交换律,我们可以用快速幂算出第二个矩阵的 n n n 次方
快速幂矩阵乘法详见:【模板】矩阵快速幂
code
#include<iostream>
#include<cstdio>
#include<cstring>
#define myc using
#define ak namespace
#define ioi std
#define int long long
myc ak ioi;
const int mod=1e9+7;
int n;
int a[3][3]={
{
},{
0,0,1},{
0,1,1}};
int ans[3][3];
int t[3][3];
void add()
{
memset(t,0,sizeof(t));
for(int i=1;i<=2;i++)
for(int j=1;j<=2;j++)
for(int k=1;k<=2;k++)
t[i][j]=(t[i][j]+ans[i][k]*a[k][j]%mod)%mod;
for(int i=1;i<=2;i++)
for(int j=1;j<=2;j++)
ans[i][j]=t[i][j];
}
void cf()
{
memset(t,0,sizeof(t));
for(int i=1;i<=2;i++)
for(int j=1;j<=2;j++)
for(int k=1;k<=2;k++)
t[i][j]=(t[i][j]+a[i][k]*a[k][j]%mod)%mod;
for(int i=1;i<=2;i++)
for(int j=1;j<=2;j++)
a[i][j]=t[i][j];
}
void ksm(int b)
{
ans[1][1]=ans[2][2]=1;
while(b)
{
if(b&1)
add();
cf();
b>>=1;
}
}
signed main()
{
cin>>n;
if(n==1||n==2)
{
cout<<1<<endl;
return 0;
}
ksm(n-2);
cout<<(ans[1][2]+ans[2][2])%mod;
}