题解 P1962 【斐波那契数列】
直接循环递推斐波那契数列,时间复杂度显然为
设
我们希望根据
上式是一个矩阵乘法递推式,初值
题目还要求我们对一个大数取模,可以直接在执行时加入取模运算。详细过程请见下面示例代码:
#include<bits/stdc++.h>
using namespace std;
#define mol 1000000007
long long n;
long long a[2][2]={{0,1},{1,1}},A[2][2];
long long f[2]={0,1},F[2];
void muladd()
{
memset(F,0,sizeof(F));
for(int i=0;i<2;i++)
for(int k=0;k<2;k++)
F[i]=(F[i]+f[k]*a[k][i])%mol;
memcpy(f,F,sizeof(F));
return;
}
void mul()
{
memset(A,0,sizeof(A));
for(int i=0;i<2;i++)
for(int j=0;j<2;j++)
for(int k=0;k<2;k++)
A[i][j]=(A[i][j]+a[i][k]*a[k][j])%mol;
memcpy(a,A,sizeof(A));
return;
}
int main()
{
scanf("%lld",&n);
while(n) // 快速幂
{
if(n%2) muladd();
mul();
n/=2;
}
printf("%d\n",f[0]%mol);
return 0;
}