P3986 斐波那契数列(exgcd&fibonacci)

Posted Harris-H

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了P3986 斐波那契数列(exgcd&fibonacci)相关的知识,希望对你有一定的参考价值。

P3986 斐波那契数列(exgcd&fibonacci)

a f i − 1 + b f i = k af_{i-1}+bf_{i}=k afi1+bfi=k

k ≤ 1 0 9 a , b > 0 k \\le 10^9\\quad a,b>0 k109a,b>0

f i − 1 + f i = f i + 1 ≤ k f_{i-1}+f_{i}=f_{i+1} \\le k fi1+fi=fi+1k

i i i不会很大。

所以可以考虑枚举 i i i

f i − 1 = x , f i = y f_{i-1}=x,f_i=y fi1=x,fi=y

a x + b y = k ax+by=k ax+by=k

因为 g c d ( x , y ) = 1 gcd(x,y)=1 gcd(x,y)=1,所以肯定有整数解。

使用 e x g c d exgcd exgcd 解出一组特解。

然后对 a a a取模求出最小正整数 a a a,答案就是 ⌈ b x ⌉ \\lceil\\dfrac{b}{x}\\rceil xb

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll gcd(ll a,ll b){
	return !b?a:gcd(b,a%b);
}
void exgcd(ll a,ll b,ll &x,ll &y){
	if(!b){
		x=1,y=0;return;
	}
	exgcd(b,a%b,y,x);y-=a/b*x;
}
ll f[70]={0,1},c,k;
const int mod=1e9+7;
int main(){
	scanf("%lld",&k);
	for(int i=2;;i++){
		f[i]=f[i-1]+f[i-2];
		if(f[i]>k){
			c=i;break;
		}
	}
	ll s=0;
	for(int i=2;i<=c;i++){
		ll a=f[i-1],b=f[i],x,y;
		exgcd(a,b,x,y);
		x*=k,y*=k;
		x=(x%b+b)%b;if(!x) x=b;
		y=(k-a*x)/b;
		if(y<=0) continue;
		s+=(y-1)/a+1;
		s%=mod;
	}
	printf("%lld\\n",s);
}

以上是关于P3986 斐波那契数列(exgcd&fibonacci)的主要内容,如果未能解决你的问题,请参考以下文章

#2019120700019-LG 斐波那契数列

斐波那契数列

斐波那契数列算法求解及速度

动态规划使用斐波那契数列引入了动态规划的概念

raptor用递归算法计算斐波那契

DP1 斐波那契数列