P3986 斐波那契数列

题目链接: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;
}
posted @ 2024-04-17 11:55  0tAp  阅读(6)  评论(0编辑  收藏  举报