题目背景
大家都知道,斐波那契数列是满足如下性质的一个数列:
•
•
•
题目描述
请你求出
输入格式
第1行:一个整数
输出格式
第1行:
输入样例#1
5
输出样例#1
5
输入样例#2
10
输出样例#2
55
说明
对于 60% 的数据:
对于 100% 的数据:
思路
矩阵乘法优化。(友情提示:一个
首先,斐波那契数列的递推式为
显然,
那么这样如果暴力做显然是
考虑到
最终时间复杂度
代码
#include <cstdio>
const int maxn=10;
const int mo=1000000007;
struct matrix
{
long long a[maxn+1][maxn+1],r,c;
matrix operator *(const matrix &other)
{
matrix res;
res.r=r;
res.c=other.c;
for(int i=1; i<=res.r; i++)
{
for(int j=1; j<=res.c; j++)
{
long long sum=0;
for(int k=1; k<=c; k++)
{
sum+=a[i][k]*other.a[k][j];
sum%=mo;
}
res.a[i][j]=sum;
}
}
return res;
}
};
long long n;
matrix t,c,ans;
matrix quickpow(matrix a,long long b,int m)
{
matrix res;
res.c=a.c;
res.r=a.r;
for(int i=1; i<=res.r; i++)
{
for(int j=1; j<=res.c; j++)
{
res.a[i][j]=0;
}
res.a[i][i]=1;
}
while(b)
{
if(b&1)
{
res=res*a;
b--;
}
b/=2;
a=a*a;
}
return res;
}
inline long long read()
{
long long x=0;
int f=1;
char ch=getchar();
while((ch<'0')||(ch>'9'))
{
if(ch=='-')
{
f=-f;
}
ch=getchar();
}
while((ch>='0')&&(ch<='9'))
{
x=x*10+ch-'0';
ch=getchar();
}
return x*f;
}
int main()
{
n=read();
if(n==1ll)
{
printf("1\n");
return 0;
}
t.r=1;
t.c=2;
t.a[1][1]=1;
t.a[1][2]=1;
c.r=2;
c.c=2;
c.a[1][1]=0;
c.a[1][2]=1;
c.a[2][1]=1;
c.a[2][2]=1;
ans=t*quickpow(c,n-2,mo);
printf("%lld\n",ans.a[1][2]);
return 0;
}