跳转至

斐波那契数列

斐波那契数列(The Fibonacci sequence,OEIS A000045)的定义如下:

F0=0,F1=1,Fn=Fn1+Fn2

该数列的前几项如下:

0,1,1,2,3,5,8,13,21,34,55,89,

卢卡斯数列

卢卡斯数列(The Lucas sequence,OEIS A000032)的定义如下:

L0=2,L1=1,Ln=Ln1+Ln2

该数列的前几项如下:

2,1,3,4,7,11,18,29,47,76,123,199,

研究斐波那契数列,很多时候需要借助卢卡斯数列为工具.

斐波那契数列通项公式

n 个斐波那契数可以在 Θ(n) 的时间内使用递推公式计算.但我们仍有更快速的方法计算.

解析解

解析解即公式解.我们有斐波那契数列的通项公式(Binet's Formula):

Fn=(1+52)n(152)n5

这个公式可以很容易地用归纳法证明,当然也可以通过生成函数的概念推导,或者解一个方程得到.

当然你可能发现,这个公式分子的第二项总是小于 1,并且它以指数级的速度减小.因此我们可以把这个公式写成

Fn=[(1+52)n5]

这里的中括号表示取离它最近的整数.

这两个公式在计算的时候要求极高的精确度,因此在实践中很少用到.但是请不要忽视!结合模意义下二次剩余和逆元的概念,在 OI 中使用这个公式仍是有用的.

卢卡斯数列通项公式

我们有卢卡斯数列的通项公式:

Ln=(1+52)n+(152)n

与斐波那契数列非常相似.事实上有:

Ln+Fn52=(1+52)n

也就是说,LnFn 恰好构成 (1+52)n 二项式展开再合并同类项后的分子系数.也就是说,Pell 方程

x25y2=4

的全体解,恰好是

xn+yn52=Ln+Fn52

恰好是卢卡斯数列和斐波那契数列.因此有

Ln25Fn2=4

矩阵形式

斐波那契数列的递推可以用矩阵乘法的形式表达:

[Fn1Fn]=[Fn2Fn1][0111]

P=[0111],我们得到

[FnFn+1]=[F0F1]Pn

于是我们可以用矩阵乘法在 Θ(logn) 的时间内计算斐波那契数列.此外,前一节讲述的公式也可通过矩阵对角化的技巧来得到.

快速倍增法

使用上面的方法我们可以得到以下等式:

F2k=Fk(2Fk+1Fk)F2k+1=Fk+12+Fk2

于是可以通过这样的方法快速计算两个相邻的斐波那契数(常数比矩乘小).代码如下,返回值是一个二元组 (Fn,Fn+1)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
pair<int, int> fib(int n) {
  if (n == 0) return {0, 1};
  auto p = fib(n >> 1);
  int c = p.first * (2 * p.second - p.first);
  int d = p.first * p.first + p.second * p.second;
  if (n & 1)
    return {d, c + d};
  else
    return {c, d};
}

性质

斐波那契数列拥有许多有趣的性质,这里列举出一部分简单的性质:

  1. 卡西尼性质(Cassini's identity):Fn1Fn+1Fn2=(1)n
  2. 附加性质:Fn+k=FkFn+1+Fk1Fn
  3. 取上一条性质中 k=n,我们得到 F2n=Fn(Fn+1+Fn1)
  4. 由上一条性质可以归纳证明,kN,Fn|Fnk
  5. 上述性质可逆,即 Fa|Fb,a|b
  6. GCD 性质:(Fm,Fn)=F(m,n)
  7. 以斐波那契数列相邻两项作为输入会使欧几里德算法达到最坏复杂度(具体参见 维基 - 拉梅).

斐波那契数列与卢卡斯数列的关系

不难发现,关于卢卡斯数列与斐波那契数列的等式,与三角函数公式具有很高的相似性.比如:

Ln+Fn52=(1+52)n

cosnx+isinnx=(cosx+isinx)n

很像.以及

Ln25Fn2=4

cos2x+sin2x=1

很像.因此,卢卡斯数列与余弦函数很像,而斐波那契数列与正弦函数很像.比如,根据

(1+52)m(1+52)n=(1+52)m+n

可以得到两下标之和的等式:

2Lm+n=5FmFn+LmLn2Fm+n=FmLn+LmFn

于是推论就有二倍下标的等式:

L2n=Ln22(1)nF2n=FnLn

这也是一种快速倍增下标的办法.同样地,也可以仿照三角函数的公式,比如奇偶性、和差化积、积化和差、半角、万能代换等等,推理出更多有关卢卡斯数列与斐波那契数列的相应等式.

斐波那契编码

我们可以利用斐波那契数列为正整数编码.根据 齐肯多夫定理,任何自然数 n 可以被唯一地表示成一些斐波那契数的和:

N=Fk1+Fk2++Fkr

并且 k1k2+2, k2k3+2, , kr2(即不能使用两个相邻的斐波那契数)

于是我们可以用 d0d1d2ds1 的编码表示一个正整数,其中 di=1 则表示 Fi+2 被使用.编码末位我们强制给它加一个 1(这样会出现两个相邻的 1),表示这一串编码结束.举几个例子:

1=1=F2=(11)F2=2=F3=(011)F6=5+1=F5+F2=(10011)F8=8=F6=(000011)F9=8+1=F6+F2=(100011)F19=13+5+1=F7+F5+F2=(1001011)F

n 编码的过程可以使用贪心算法解决:

  1. 从大到小枚举斐波那契数 Fi,直到 Fin
  2. n 减掉 Fi,在编码的 i2 的位置上放一个 1(编码从左到右以 0 为起点).
  3. 如果 n 为正,回到步骤 1.
  4. 最后在编码末位添加一个 1,表示编码的结束位置.

解码过程同理,先删掉末位的 1,对于编码为 1 的位置 i(编码从左到右以 0 为起点),累加一个 Fi+2 到答案.最后的答案就是原数字.

模意义下周期性

对于模 m 意义下的斐波那契数列,可以容易地使用抽屉原理证明,该数列是有周期性的.由于斐波那契数每一项的计算都依赖于前两项的取值,所以需要用相邻斐波那契数组成的数对描述数列当且所处的状态.考虑模意义下前 m2+1 个斐波那契数对:

(F0, F1), (F1, F2), , (Fm2, Fm2+1)

m 的剩余系大小为 m,这意味着至多只可能有 m2 种互不相同的数对.因此,在前 m2+1 个数对中必有两个相同的数对,于是从这两个数对可以往后生成相同的斐波那契数列.那么,斐波那契数列就是周期性的,且(最小正)周期不会超过 m2

Pisano 周期

m 意义下斐波那契数列的最小正周期被称为 Pisano 周期(Pisano period,皮萨诺周期,OEIS A001175).本文中用 π(m) 表示模 m 的 Pisano 周期.

这一观察可以用于计算第 n 项斐波那契数模 m 的值.如果 n 非常大,就需要计算斐波那契数模 m 的周期.当然,只需要计算周期,不一定是最小正周期.

为此,有如下结论:

  1. 对于互素的模数 m1,m2,有 π(m1m2)=lcm(π(m1),π(m2))
  2. 对于素数 p 和正整数 e,有 π(pe)pe1π(p)
  3. 对于 m=2e (eN+),有 π(m)=32e1
  4. 对于 m=5e (eN+),有 π(m)=45e
  5. 最后,对于素数 p±1(mod10),有 π(p)(p1);对于素数 p±3(mod10),有 π(p)2(p+1)

综合这些情形,可以说明:模 m 的 Pisano 周期不会超过 6m,等号当且仅当 m=2×5e (eN+) 时取得.

利用上述结论,可以基于素因数分解算法,得到如下快速计算 Pisano 周期的方法:

参考代码
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
// Get a period of Fibonacci sequence mod m.
// Not necessarily be the exact Pisano period.
uint32_t calc_cycle_from_mod(uint32_t m) {
  uint32_t res = 1;
  for (auto pe : factorize(m)) {
    auto p = pe.first;
    auto e = pe.second;
    uint64_t cur = pow(p, e - 1);
    if (p == 2) {
      cur *= 3;
    } else if (p == 5) {
      cur *= 20;
    } else if (p % 5 == 1 || p % 5 == 4) {
      cur *= p - 1;
    } else {
      cur *= 2 * (p + 1);
    }
    res = lcm(res, cur);
  }
  return res;
}

这样得到的周期可能只是 Pisano 周期的一个倍数.要得到精确的 Pisano 周期,可以进一步考察该周期的因数;或者,可以直接通过 BSGS 算法O(m) 的时间复杂度计算.

证明

最后,本文简要证明上述关于 Pisano 周期的结论.值得说明的是,利用下文说明的方法,类似的结论可以推广到一般的二阶常系数线性齐次递推数列.尽管具体的常数有所差异,这些数列模 m 的 Pisano 周期都是 O(m) 的.

第一个观察是:利用 中国剩余定理,可以将讨论限制在素数幂模的情形.设 m1,m2 是两个互素的模数.斐波那契数列在模 m1 下的周期是 π(m1) 及其倍数,在模 m2 下的周期是 π(m2) 及其倍数,所以它在模 m1m2 下的最小正周期则恰为 π(m1)π(m2) 的最小公倍数.这就是前文的结论 1.

另一个观察是:模 m 下的 Pisano 周期,其实是最小的正整数 k,使得

Ak=(1110)kI(modm).

也就是说,它其实是矩阵 A 在模 m1

对于素数幂模 m=pe 的情形,可以通过经典的升幂论证联系到相应的素数模的情形.设 k=π(pe),就存在二阶方阵 Λ,使得

Ak=peΛ+I

成立.故而,由 二项式定理 可知

Akp=(peΛ+I)p=I+i=1p(pi)(peΛ)iI(modpe+1).

因此,由 阶的性质,有 π(pe+1)kp=pπ(pe).对 e 归纳可知,π(pe)pe1π(p) 总是成立.

对于素数模 p 的情形,本文讨论两种证明方式.

一种是利用斐波那契数列的通项公式:

Fn=15(1+52)n15(152)n.

将它用二项式定理展开,并消去根式项:

Fn=12n1i=0(n1)/2(n2i+1)5i.

对于 p=2,这一表达式无法直接取模,但可以验证对应的 Pisano 周期为 π(2)=3.对于 p=5,有 Fnn3n1(modp),可以直接验证对应的 Pisano 周期为 π(5)=20.对于剩余的奇素模数,可以分为两种情形:

  • 如果 p1,4(mod5),就有

    Fp12p1(pp)5(p1)/21(modp),Fp+112p((p+11)+(p+1p)5(p1)/2)1(modp).

    化简过程中,利用了如下结论:由 Lucas 定理,对于 0<k<p 都有 (pk)0(modp),而对于 1<k<p 都有 (p+1k)0(modp);由 Fermat 小定理,有 2p15p11(modp);对于 p1,4(mod5),都有 p 是模 5 的二次剩余,利用 二次互反律,也有 5 是模 p 的二次剩余,故而 5(p1)/21(modp).由此,有 (Fp,Fp+1)(F1,F2)(modp),所以 (p1) 是模 p 的一个周期.所以,π(p)(p1)

  • 如果 p2,3(mod5),就有

    F2p122p1(2pp)5(p1)/21(modp),F2p+1122p((2p+11)+(2p+1p)5(p1)/2+(2p+12p+1)5p)1(modp).

    化简过程中,利用了如下结论:由 Lucas 定理,对于 0<k<pp<k<2p 都有 (pk)0(modp),以及 (2pp)2(modp),而对于 1<k<pp+1<k<2p 都有 (pk)0(modp),以及 (2p+1p)2(modp);由 Fermat 小定理,有 2p15p11(modp);对于 p2,3(mod5),都有 p 是模 5 的二次非剩余,利用二次互反律,也有 5 是模 p 的二次非剩余,故而 5(p1)/21(modp).由此,有 (F2p,F2p+1)(F2,F1)(modp),所以 2(p+1) 是模 p 的一个周期.所以,π(p)2(p+1)

这就完成了证明.这一方法的局限性在于它高度依赖于斐波那契数列的通项公式,所以较难直接推广到一般的情形.

另一种证明方式则是试图直接计算矩阵 A=(1110) 的阶.它的 特征多项式f(x)=x2x1,对应的判别式为 Δ=5.对于模 p=5,有 Δ0(mod5),矩阵 A 有两个相同特征值 λ=3,且不能对角化,需要单独计算.对于模 p1,4(mod5),由二次互反律可知,判别式 Δ=5 是模 p 的二次剩余,矩阵 A 在域 Fp 内有两个相异特征值 λ1λ2,矩阵 A 的阶就是 lcm(ord(λ1),ord(λ2)),必然整除 |Fp×|=p1.对于模 p2,3(mod5),由二次互反律可知,判别式 Δ=5 是模 p 的二次非剩余,矩阵 A 在域 Fp 内没有特征值,而只有在 扩域 Fp[5] 内才有两个相异特征值 λ1λ2,由于 Frobenius 自同态 xxp 将两根交换,有 λ2=λ1p,故而 λ1p+1=λ2p+1=λ1λ2=1,亦即 λ12(p+1)=λ22(p+1)=1,由此,矩阵 A 的阶就是 lcm(ord(λ1),ord(λ2)),必然整除 2(p+1).这就得到了与前种方法一致的结论.

综上,对于不同的情形,相应地有:

  • π(2e)=322e, 14π(5e)=5e
  • p±1(mod10) 时,π(pe)(p1)pe1,所以 π(pe)pe
  • p±3(mod10) 时,14π(pe)p+12pe1,所以 14π(pe)pe

所以,利用结论 1,对于一般的模数 m=ipiei,有

π(m)=lcm{π(piei):piP}lcm{π(piei):pi=2 or pi±1 (mod10)}4lcm{π(piei)/4:pi=5 or pi±3 (mod10)}{π(piei):pi=2 or pi±1 (mod10)}4{π(piei)/4:pi=5 or pi±3 (mod10)}32{piei:pi=2 or pi±1 (mod10)}4{piei:pi=5 or pi±3 (mod10)}=6m.

这就说明了斐波那契数列模 m 的 Pisano 周期总是不超过 6m,而且等号当且仅当在 m=25e 处取得.

习题

参考文献与注释

本页面主要译自博文 Числа Фибоначчи 与其英文翻译版 Fibonacci Numbers.其中俄文版版权协议为 Public Domain + Leave a Link;英文版版权协议为 CC-BY-SA 4.0.内容有改动.


  1. 严格来说,它是矩阵 A 在一般线性群 GL2(Zm) 中的阶.