题目链接:P3986 斐波那契数列
推式子
观察题目所给的序列:
根据题意我们可以知道k=f(i-1)+f(i-2)
那么浅浅的推一下就可以发现:
k=f(3)时 k=a+b
k=f(4)时 k=a+2b
k=f(5)时 k=2a+3b
......
故可以得出
k=fib(i)a+fib(i+1)b
因为a,b属于正整数
故 fib(n-2)+fib(n-1)>k时停止
那么我们只要稍稍枚举一下,并且根据扩展欧几里得求出符合条件的解的个数即可
代码如下
#include<bits/stdc++.h>
using namespace std;
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define dwn(i,a,b) for(int i=(a);i>=(b);i--)
#define int long long
const int mod=1e9+7,N=45;
int k;
int f[N];
int _exgcd_(int a,int b,int &x,int &y)
{
if(b==0)
{
x=1,y=0;return a;
}
int d=_exgcd_(b,a%b,x,y);
int z=x;
x=y,y=z-y*(a/b);
return d;
}
signed main()
{
cin>>k;
int ans=0;
f[1]=1,f[2]=1;
rep(i,3,N)f[i]=f[i-1]+f[i-2];
int x,y;
rep(i,2,N)
{
if(f[i]+f[i-1]>k)break;
int a=f[i-1],b=f[i];
int d=_exgcd_(a,b,x,y);
x=((x*k)%b+b)%b;
if(x==0)x=b;
y=(k-a*x)/b;
if(y<0)continue;
ans=(ans+(long long)ceil(1.0*y/a))%mod;
}
cout<<(ans%mod);
return 0;
}
标签:fib,int,rep,P3986,exgcd,斐波,那契
From: https://www.cnblogs.com/0tAp-Z/p/18140266