0297 齐肯多夫表示
* * * *
拉格朗日计划
* * * *
齐肯多夫表示

斐波那契数列的每一项都由前两项相加而得,从1和2开始,前10项依次是:1、2、3、5、8、13、21、34、55、89。

每一个正整数或者是数列中的一项,或者以唯一地写作斐波那契数列中若干个非连续项的和。例如,$100=3+8+89$。这样的和称为该数的齐肯多夫表示。

记$z(n)$为$n$的齐肯多夫表示中的项数,例如$z(5)=1$、$z(14)=2$、$z(100)=3$,等等。此外$\sum_{n=1}^{10^6-1}z(n)=7894453$。

求$\sum_{n=1}^{10^{17}-1}z(n)$。

本题难度:



解答

记$f(x)=\sum_{n=1}^{x}z(n)$,$g(x)$为不超过$x$的最大斐波那契数。

显然,要表示$1$到$g(x)-1$之间的数无需用到$g(x)$,而$g(x)$到$x$之间的每个数减去$g(x)$后就又转化了前者的情形,因此有递推公式 $$f(x)=f(g(x)-1)+f(x-g(x))+x-g(x)+1,$$ 以及初值$f(0)=0$,递推计算即得结果$2252639041804718029$。

import bisect
from functools import *

n=10**17-1
a=[1,2]

while a[-1]<=n:
    a.append(a[-1]+a[-2])

s=set(a)

g=lambda x:0 if x<=0 else a[bisect.bisect(a,x)-1]

@cache
def f(x):
    if x==0:
        return 0
    else:
        return f(g(x)-1)+f(x-g(x))+x-g(x)+1

print(f(n))