洛谷 P3986 斐波那契数列

P3986 斐波那契数列

题目描述

定义一个数列:
f ( 0 ) = a , f ( 1 ) = b , f ( n ) = f ( n − 1 ) + f ( n − 2 ) f(0) = a, f(1) = b, f(n) = f(n - 1) + f(n - 2) 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

输入 1

复制代码
19260817

输出 1

复制代码
34166325

输入输出样例 2

输入 2

复制代码
1000000000

输出 2

复制代码
773877569

说明/提示

1 ≤ k ≤ 10^9

EXP:

针对于该函数数列中的数据分别为 : a + b , a + 2 b , 2 a + 3 b , 3 a + 5 b 即 a , b 的系数是斐波那契数列的数据。 1 ≤ k ≤ 1 0 9 , 针对 40 项左右的斐波那契数就已经超过该范围,并且 a , b 都是正整数。所以可以遍历斐波那契数列判断 a . k = a f [ x − 1 ] + b f [ x ] = > b f [ x ] = k − a f [ x − 1 ] = > b = ( k − a f [ x − 1 ] ) / f [ x ] 因为 a , b 正整数的缘故。 k − a f [ x − 1 ] ≡ 0 ( m o d f [ x ] ) = > k ≡ a f [ x − 1 ] ( m o d f [ x ] ) , 因为 g c d ( f [ x ] , f [ x − 1 ] ) = 1 a ≡ ( k ∗ f − 1 [ x − 1 ] ( m o d f [ x ] ) ) ( m o d f [ x ] ) 并且要保证 b > 0 , 即判断 a < k / f [ x − 1 ] 针对于该函数数列中的数据分别为:a+b,a+2b,2a+3b,3a+5b即a,b的系数是斐波那契数列的数据。\\ 1≤k≤10^9,针对40项左右的斐波那契数就已经超过该范围,并且a,b都是正整数。所以可以遍历斐波那契数列判断a.\\ k = af[x-1] + bf[x]=>bf[x] = k - af[x-1]=>b=(k-af[x-1])/f[x]因为a,b正整数的缘故。\\ k-af[x-1]\equiv0(modf[x])=>k\equiv af[x-1](modf[x]),因为gcd(f[x],f[x-1])=1\\ a\equiv (k * f^{-1}[x-1](modf[x]))(modf[x])并且要保证b >0,即判断a<k/f[x-1] 针对于该函数数列中的数据分别为:a+b,a+2b,2a+3b,3a+5b即a,b的系数是斐波那契数列的数据。1≤k≤109,针对40项左右的斐波那契数就已经超过该范围,并且a,b都是正整数。所以可以遍历斐波那契数列判断a.k=af[x−1]+bf[x]=>bf[x]=k−af[x−1]=>b=(k−af[x−1])/f[x]因为a,b正整数的缘故。k−af[x−1]≡0(modf[x])=>k≡af[x−1](modf[x]),因为gcd(f[x],f[x−1])=1a≡(k∗f−1[x−1](modf[x]))(modf[x])并且要保证b>0,即判断a<k/f[x−1]

python 复制代码
# coding: utf-8
MOD = 10 ** 9 + 7

def gcd_extended(a,b):
    """
    扩展欧几里得算法
    返回一个元组(d,x,y) 使得 d = gcd(a,b) = ax + by
    """
    if a == 0:
        return (b,0,1)
    gcd , x1 , y1 = gcd_extended(b % a , a)

    x = y1 - (b // a) * x1
    y = x1
    return (gcd,x,y)

def mod_inverse(a,m):
    """
    求模逆元
    使用扩展欧几里得算法返回a在m下的逆元
    如果没有逆元返回None
    """
    gcd, x, y = gcd_extended(a,m)
    if gcd != 1:
        return None # 如果a 和 m不互素
    else:
        return x % m # 返回逆元

def matrix_mul(A, B):
    """矩阵乘法"""
    return [[sum(a * b for a, b in zip(col, row)) for col in zip(*B)] for row in A]


def matrix_pow(A, n):
    """矩阵快速幂"""
    size_ = len(A)
    if n == 0:
        res = [[0 for _ in range(size_)] for _ in range(size_)]
        for i in range(size_):
            res[i][i] = 1
    elif n == 1:
        return A
    else:
        y = matrix_pow(A, n // 2)
        if n & 1:
            return matrix_mul(matrix_mul(y, y), A)
        return matrix_mul(y, y)


K = int(input())
counter = 0
A = [
    [0, 1],
    [1, 1]
]
# 遍历前面的斐波那契数列
for i in range(2,42):
    temp = matrix_mul([[0,1]],matrix_pow(A,i - 1))
    f_x = temp[0][1]
    f_x_1 = temp[0][0]
    # 计算范围内最小的a
    a = (K * mod_inverse(f_x_1,f_x)) % f_x
    # 求取k / f[x-1]	由于向下取整,所以b > 0时要求是个足够大的正整数
    target = K // f_x_1 - 1
    if a < target:
        # 如果a = 0则a本身不在计算
        if a == 0:
            counter -= 1
        # 根据a的大小,加上a + k_counter * f[x] 的所有a
        counter = (counter + 1 + (target - a) // f_x) % MOD
print(counter)
相关推荐
共享家95271 分钟前
排序算法实现:插入排序与希尔排序
c语言·开发语言·数据结构·算法·排序算法
Pocker_Spades_A4 分钟前
Python刷题:流程控制(上)
开发语言·python
Pocker_Spades_A4 分钟前
深度洞察:DeepSeek 驱动金融行业智能化转型变革
数据库·python·oracle·金融·deepseek
记得早睡~5 分钟前
leetcode501-二叉搜索树中的众数
javascript·数据结构·算法·leetcode
被AI抢饭碗的人10 分钟前
算法题(102):八皇后
算法·深度优先
仙人掌_lz15 分钟前
RAG各类方法python源码解读与实践:RAG技术综合评测【3万字长文】
开发语言·人工智能·python·深度学习·ai·jupyter·rag
无敌的牛15 分钟前
算法刷题力扣
算法·leetcode·职场和发展
江沉晚呤时15 分钟前
深入解析 .NET Core 垃圾回收(GC):概念、工作原理与优化策略
java·jvm·算法·c#·asp.net·.netcore·net
梓羽玩Python17 分钟前
一款刚刚开源的TTS语音模型!25ms超低延迟支持实时对话,4种规格适配全场景!
人工智能·python·github
uhakadotcom18 分钟前
CUDA编程入门:加速计算的强大工具
算法·面试·架构