题目描述

定义一个数列:

f(0)=a,f(1)=b,f(n)=f(n−1)+f(n−2)

其中 a,b均为正整数,n≥2 。

问有多少种 (a,b),使得 k 出现在这个数列里,且不是前两项。

由于答案可能很大,你只需要输出答案模 10^9 + 7 的结果即可。

输入输出格式

输入格式:

一行一个整数 k 。

输出格式:

一行一个数,表示答案模10^9 + 7的结果。

输入输出样例

输入样例#1:

19260817
输出样例#1:

34166325
输入样例#2:

1000000000
输出样例#2:

773877569

说明

1≤k≤109

Solution:

  一道趣味数学题,想了有快40多分钟。。。

  本题可以枚举系数用扩展欧几里德求解通解,然后求正整数解个数,显然当某次无整数解时,再往后也不会再有正整数解了(很简单的道理,等下我的方法里有解释)。

  讲讲我的算法,个人认为上述的方法简单些,但是我想到一个很特殊的斐波拉契的性质 F[i]*F[i+3]-F[i+1]*F[i+2]=(-1)i-1 于是入坑用了一个稍微复杂但绝对好理解的算法。

  然后今天月考炸完,在机房无聊在白板上写本题详细思路(为写博做准备),结果发现本题要用我的方法写的话实在是长。

  这是我在黑板上写的:

  肯定不够清晰,所以还是解释一波:

  题意是给定一个k,问有多少个f[1]=a,f[2]=b,使得k出现在该斐波拉契数列中。

  等价于求解 a+b=k、a+2b=k、2a+3b=k、3a+5b=k…的以相邻两项斐波拉契数为系数的不定方程的正整数解的个数。

  因为题目中说道a、b≥1,所以当斐波拉契数的某相邻两项f[i]+f[i+1]>k时便可不用在求不定方程了(显然无正整数解)。

  于是可以枚举相邻的两项斐波拉契数作系数,然后累加正整数解的个数。

   我们由裴蜀定理可知: $$ax+by=c \quad a,b,c\in Z*$$

  有整数解的充要条件是: $$gcd(a,b)|c$$

  证明:

  $\because \quad$ $a=pgcd(a,b),\quad$ $b=qgcd(a,b)$

$\therefore \quad$ $ax+by=pgcd(a,b)x+qgcd(a,b)y=(px+qy)*gcd(a,b)=c$

  $\because \quad$ $(px+qy),gcd(a,b)\in Z*$

  $\therefore \quad$ $gcd(a,b)|c$

  

  不妨设$x,y$为 $ax+by=c$ 的一组解,则由解$x,y$可推出其它解为:

  $x1=x+\frac{b}{gcd(a,b)}*t,\quad$ $y2=x-\frac{a}{gcd(a,b)}*t\quad,t\in Z*$

  证明:

  $\because \quad ax+by=c$

  $\therefore \quad ax+by+\frac{ab}{gcd(a,b)}*t-\frac{ab}{gcd(a,b)}*t=c$

  $\therefore \quad a(x+\frac{b}{gcd(a,b)}*t)+b(y-\frac{a}{gcd(a,b)}*t)=c$

  $\therefore \quad$ $x1=x+\frac{b}{gcd(a,b)}*t,\quad$ $y2=x-\frac{a}{gcd(a,b)}*t\quad,t\in Z*$

  

  然后我们以斐波拉契中的相邻两项f[i]和f[i+1]为系数

  不难发现$f[i]*f[i+3]-f[i+1]*f[i+2]=(-1)^{i-1}$

  证明:

  设$f[i]=a,f[i-1]=b\quad$ 则$f[i+1]=a+b,f[i+2]=2a+b,f[i+3]=3a+2b$

  原式$=a*(3a+2b)-(a+b)*(2a+b)$

    $=a^2-b^2-ab$

    $=(a-b)(a+b)-ab$

    $=f[i-2]*f[i+1]-f[i-1]*f[i]$

  继续将新式子往下递归

  1、当$2|i$,必定递归到$f[0]*f[3]-f[1]*f[2]=-1$(注意到$f[0]$无意义,所以$f[0]=0$),所以i为偶数时$f[i]*f[i+3]-f[i+1]*f[i+2]=-1$

  2、否则,必定递归到$f[1]*f[4]-f[2]*f[3]=1$,所以i为奇数时$f[i]*f[i+3]-f[i+1]*f[i+2]=1$

  $\therefore \quad$ $f[i]*f[i+3]-f[i+1]*f[i+2]=(-1)^{i-1}$

  有了上面这个性质,易得题目中的$f[i]x+f[i+1]y=k$必定有通解:

  $x=(-1)^{i-1}*k*f[i+3],\quad$ $y=(-1)^{i}*k*f[i+2]$

  然后易得斐波拉契数列的相邻两项$f[i]$和$f[i+1]$互质,即$gcd(f[i],f[i+1])=1$,  

  证明(由欧几里德定理):

  $\because \quad$ $gcd(f[i],f[i+1])=gcd(f[i],f[i+1]-f[i])=gcd(f[i],f[i-1])…=gcd(f[1],f[2])=1$

  $\therefore \quad$ $gcd(f[i],f[i+1])=1$

  于是由上述性质可知:

  $f[i]x+f[i+1]y=k$的整数解为$x1=(-1)^{i-1}*k*f[i+3]+f[i+1]*t,\quad$ $y1=(-1)^{i}*k*f[i+2]-f[i]*t,\quad t\in Z*$

  显然由于$(-1)^{i-1},(-1)^{i}$中必定有一个为-1,于是$x$和$y$中有且仅有一负数。

  1、当$x<0$,先使x变为最小整数解。

    则xmin $=x+(\frac{\left| x\right|}{f[i+1]}+1)*f[i+1]$

    则ymax $=y-(\frac{|x|}{f[i+1]}+1)*f[i]$

    此时求其它正整数解时$x$单调递增,$y$单调递减。

    $\therefore \quad$ 此时的正整数解的个数$=\lceil \frac{ymax}{f[i]} \rceil$

  2、当$y<0$,和上面同理知此时的正整数解个数$=\lceil \frac{xmax}{f[i+1]} \rceil$

  

  按照上述方法本题便能完美的解决。

  由于斐波拉契数最多到第90多项时就爆long long了,所以本题此方法复杂度O(n),n≤92。

代码:

#include<bits/stdc++.h>
#define il inline
#define ll long long
using namespace std; const ll mod=1e9+;
ll f[],x,y,n,i,ans;
int main()
{
cin>>n;
f[]=f[]=;ans=n-;
for(i=;i<=;i++){f[i]=f[i-]+f[i-];if(f[i]>=n)break;}
//cout<<i<<endl;
for(int j=;j<=i;j++){
int q=pow(-,j-);
x=n*q*f[j+],y=-n*q*f[j+];
if(x<){y-=(abs(x)/f[j+]+)*f[j];if(y>)ans=ans+ceil(1.0*y/f[j]);ans%=mod;}
else if(y<){x-=(abs(y)/f[j]+)*f[j+];if(x>)ans=ans+ceil(1.0*x/f[j+]);ans%=mod;}
}
cout<<ans;
return ;
}

P3986 斐波那契数列的更多相关文章

  1. P3986 斐波那契数列——数学(EXGCD)

    https://www.luogu.org/problem/P3986 很久很久以前,我好像写过exgcd,但是我已经忘了: 洛谷上搜EXGCD搜不到,要搜(扩展欧几里得) 这道题就是ax+by=k, ...

  2. [Luogu P3986] 斐波那契数列 (逆元)

    题面 传送门:https://www.luogu.org/problemnew/show/P3986 Solution 这是一道很有意思的数论题. 首先,我们可以发现直接枚举a和b会T的起飞. 接下来 ...

  3. C#求斐波那契数列第30项的值(递归和非递归)

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...

  4. 斐波拉契数列加强版——时间复杂度O(1),空间复杂度O(1)

    对于斐波拉契经典问题,我们都非常熟悉,通过递推公式F(n) = F(n - ) + F(n - ),我们可以在线性时间内求出第n项F(n),现在考虑斐波拉契的加强版,我们要求的项数n的范围为int范围 ...

  5. js中的斐波那契数列法

    //斐波那契数列:1,2,3,5,8,13…… //从第3个起的第n个等于前两个之和 //解法1: var n1 = 1,n2 = 2; for(var i=3;i<101;i++){ var ...

  6. 剑指Offer面试题:8.斐波那契数列

    一.题目:斐波那契数列 题目:写一个函数,输入n,求斐波那契(Fibonacci)数列的第n项.斐波那契数列的定义如下: 二.效率很低的解法 很多C/C++/C#/Java语言教科书在讲述递归函数的时 ...

  7. 算法: 斐波那契数列C/C++实现

    斐波那契数列: 1,1,2,3,5,8,13,21,34,....     //求斐波那契数列第n项的值 //1,1,2,3,5,8,13,21,34... //1.递归: //缺点:当n过大时,递归 ...

  8. 洛谷P1962 斐波那契数列 || P1349 广义斐波那契数列[矩阵乘法]

    P1962 斐波那契数列 大家都知道,斐波那契数列是满足如下性质的一个数列: • f(1) = 1 • f(2) = 1 • f(n) = f(n-1) + f(n-2) (n ≥ 2 且 n 为整数 ...

  9. Python递归及斐波那契数列

    递归函数 在函数内部,可以调用其他函数.如果一个函数在内部调用自身本身,这个函数就是递归函数.举个例子,我们来计算阶乘 n! = 1 * 2 * 3 * ... * n,用函数 fact(n)表示,可 ...

随机推荐

  1. P1199 三国游戏

    题目描述 小涵很喜欢电脑游戏,这些天他正在玩一个叫做<三国>的游戏. 在游戏中,小涵和计算机各执一方,组建各自的军队进行对战.游戏中共有 N 位武将(N为偶数且不小于 4),任意两个武将之 ...

  2. 【机器学习笔记】EM算法及其应用

    极大似然估计 考虑一个高斯分布\(p(\mathbf{x}\mid{\theta})\),其中\(\theta=(\mu,\Sigma)\).样本集\(X=\{x_1,...,x_N\}\)中每个样本 ...

  3. Linux下安装Nginx并实现socket代理

    nginx可以使用各平台的默认包来安装,本文是介绍使用源码编译安装,包括具体的编译参数信息. 正式开始前,编译环境gcc g++ 开发库之类的需要提前装好,这里默认你已经装好. ububtu平台编译环 ...

  4. PyYAML学习第一篇

    1. YAML是一种交互式和可读性强的脚本语言.脚本语言都是解释性语言. PyYAML是YAML语言的编辑器和解释器.在python语言里面有PyYAML的安装包. 相关学习文档:http://pyy ...

  5. ping telnet 指令

    Ping 一 作用 ping能够辨别网络功能的某些状态,这些状态是日常网络故障诊断的基础.Ping能够识别连接的二进制状态(看是否连通).Ping命令通过过向计算机发送ICMP回应报文并监听回应报文的 ...

  6. Andorid自定义attr的各种坑

    本文来自网易云社区 作者:孙有军 在开发Andorid应用程序中,经常会自定义View来实现各种各样炫酷的效果,在实现这吊炸天效果的同时,我们往往会定义很多attr属性,这样就可以在XML中配置我们想 ...

  7. NPOI List数据源 导出excel

    List数据源生成HSSFWorkbook通用方法: public class WorkBook { public static HSSFWorkbook BuildSwitchData<T&g ...

  8. MySQL日期、字符串、时间戳互转

    平时比较常用的时间.字符串.时间戳之间的互相转换,虽然常用但是几乎每次使用时候都喜欢去搜索一下用法:本文将作为一个笔记,整理一下三者之间的 转换(即:date转字符串.date转时间戳.字符串转dat ...

  9. TPO-11 C1 Use the gym pass

    TPO-11 C1 Use the gym pass 第 1 段 1.Listen to a conversation between a student and a university emplo ...

  10. leetcode-对称二叉树

    对称二叉树     给定一个二叉树,检查它是否是镜像对称的. 例如,二叉树 [1,2,2,3,4,4,3] 是对称的. 1 / \ 2 2 / \ / \ 3 4 4 3 但是下面这个 [1,2,2, ...