Dãy Fibonacci
Dãy Fibonacci (The Fibonacci sequence, OEIS A000045) được định nghĩa như sau:
Một vài số đầu tiên:
Dãy Lucas
Dãy Lucas (The Lucas sequence, OEIS A000032) được định nghĩa:
Một vài số đầu:
Nghiên cứu Fibonacci thường cần dùng dãy Lucas làm công cụ.
Công thức tổng quát của Fibonacci
Số Fibonacci thứ \(n\) có thể tính trong \(\Theta(n)\) bằng công thức truy hồi, nhưng ta vẫn có cách nhanh hơn.
Nghiệm giải tích
Nghiệm giải tích là công thức tường minh. Ta có công thức Binet:
Công thức này dễ chứng minh bằng quy nạp, hoặc suy ra từ hàm sinh, hoặc giải phương trình.
Bạn sẽ thấy hạng tử thứ hai ở tử luôn nhỏ hơn \(1\) và giảm theo cấp số nhân. Vì vậy có thể viết:
Dấu ngoặc vuông là làm tròn tới số nguyên gần nhất.
Hai công thức này yêu cầu độ chính xác rất cao nên thực tế ít dùng. Tuy vậy, trong OI, kết hợp với khái niệm thặng dư bậc hai và nghịch đảo modulo, công thức này vẫn hữu ích.
Công thức tổng quát của Lucas
Ta có:
Rất giống Fibonacci. Thật vậy:
Nói cách khác, \(L_n\) và \(F_n\) đúng là các hệ số sau khi khai triển nhị thức của \(\left(\frac{1 + \sqrt{5}}{2}\right)^n\) rồi gom nhóm. Điều này cũng cho thấy nghiệm của phương trình Pell
thỏa:
chính là dãy Lucas và Fibonacci. Do đó:
Dạng ma trận
Truy hồi Fibonacci có thể biểu diễn bằng nhân ma trận:
Đặt \(P = \begin{bmatrix}0 & 1 \cr 1 & 1 \cr\end{bmatrix}\), ta được:
Vì vậy có thể tính Fibonacci trong \(\Theta(\log n)\) bằng nhân ma trận. Ngoài ra, công thức tường minh ở trên cũng có thể suy ra bằng chéo hóa ma trận.
Phương pháp nhân đôi nhanh
Từ trên ta có:
Từ đó có thể tính nhanh hai số Fibonacci liên tiếp (hằng số tốt hơn nhân ma trận). Code trả về cặp \((F_n,F_{n+1})\):
1 2 3 4 5 6 7 8 9 10 | |
Tính chất
Dãy Fibonacci có nhiều tính chất thú vị, dưới đây là một số tính chất cơ bản:
- Đẳng thức Cassini: \(F_{n-1} F_{n+1} - F_n^2 = (-1)^n\).
- Tính chất cộng chỉ số: \(F_{n+k} = F_k F_{n+1} + F_{k-1} F_n\).
- Lấy \(k = n\) ở trên: \(F_{2n} = F_n (F_{n+1} + F_{n-1})\).
- Từ đó suy ra \(\forall k\in \mathbb{N},F_n|F_{nk}\).
- Chiều ngược: \(\forall F_a|F_b,a|b\).
- Tính chất GCD: \((F_m, F_n) = F_{(m, n)}\).
- Dùng hai số Fibonacci liên tiếp làm đầu vào khiến thuật toán Euclid đạt độ phức tạp tệ nhất (xem Wikipedia - Lame).
Quan hệ giữa Fibonacci và Lucas
Không khó thấy các đẳng thức giữa Lucas và Fibonacci giống các công thức lượng giác. Ví dụ:
giống:
và
giống:
Do đó Lucas giống cos, Fibonacci giống sin. Ví dụ từ:
suy ra:
Từ đó có công thức nhân đôi chỉ số:
Đây cũng là một cách nhân đôi nhanh. Tương tự có thể suy ra nhiều đẳng thức khác kiểu lượng giác.
Mã hóa Fibonacci
Ta có thể dùng Fibonacci để mã hóa số nguyên dương. Theo định lý Zeckendorf, mọi số tự nhiên \(n\) có biểu diễn duy nhất dưới dạng tổng các số Fibonacci:
và \(k_1 \ge k_2 + 2,\ k_2 \ge k_3 + 2,\ \ldots,\ k_r \ge 2\) (không dùng hai số Fibonacci liên tiếp).
Ta mã hóa một số nguyên dương bằng \(d_0 d_1 d_2 \dots d_s 1\), trong đó \(d_i=1\) nghĩa là \(F_{i+2}\) được dùng. Thêm một bit 1 ở cuối để đánh dấu kết thúc (vì vậy sẽ có hai bit 1 liên tiếp). Ví dụ:
Quá trình mã hóa dùng tham lam:
- Duyệt Fibonacci từ lớn tới nhỏ cho đến khi \(F_i\le n\).
- Trừ \(n\) đi \(F_i\), đặt 1 tại vị trí \(i-2\) của mã (đánh số vị trí từ trái sang phải bắt đầu 0).
- Nếu \(n>0\) quay lại bước 1.
- Thêm một bit 1 ở cuối để đánh dấu kết thúc.
Giải mã tương tự: bỏ bit cuối, với mỗi vị trí \(i\) có bit 1 (đánh số từ trái sang phải bắt đầu 0), cộng \(F_{i+2}\) vào đáp án. Kết quả là số ban đầu.
Tính chu kỳ theo modulo
Xét Fibonacci modulo \(p\), dùng nguyên lý Dirichlet có thể chứng minh dãy có chu kỳ. Xét \(p^2+1\) cặp liên tiếp:
Có \(p\) lớp dư, nên trong \(p^2+1\) cặp sẽ có hai cặp trùng nhau. Từ đó sinh ra cùng dãy phía sau, nên dãy có chu kỳ.
Chu kỳ Pisano
Chu kỳ dương nhỏ nhất của Fibonacci modulo \(m\) gọi là chu kỳ Pisano (Pisano periods, OEIS A001175).
Chu kỳ Pisano không vượt quá \(6m\), và chỉ đạt bằng khi \(m=2\times 5^k\).
Khi cần tính \(F_n \bmod m\) với \(n\) rất lớn, cần tìm chu kỳ (không nhất thiết là chu kỳ nhỏ nhất).
Dễ kiểm tra: modulo 2 có chu kỳ 3, modulo 5 có chu kỳ 20.
Nếu \(a\) và \(b\) nguyên tố cùng nhau, chu kỳ Pisano của \(ab\) là bội chung nhỏ nhất của chu kỳ của \(a\) và \(b\).
Tính chu kỳ còn cần các kết luận sau:
Kết luận 1: Với số nguyên tố lẻ \(p\equiv 1,4 \pmod 5\), \(p-1\) là chu kỳ của Fibonacci modulo \(p\). Nghĩa là chu kỳ Pisano chia hết \(p-1\).
Chứng minh:
Khi đó \(5^\frac{p-1}{2} \equiv 1\pmod p\).
Khai triển nhị thức:
Vì \(F_p\) và \(F_{p+1}\) đều đồng dư 1 như \(F_1\) và \(F_2\), nên \(p-1\) là chu kỳ.
Kết luận 2: Với số nguyên tố lẻ \(p\equiv 2,3 \pmod 5\), \(2p+2\) là chu kỳ của Fibonacci modulo \(p\), tức chu kỳ Pisano chia hết \(2p+2\).
Chứng minh:
Khi đó \(5^\frac{p-1}{2} \equiv -1\pmod p\).
Khai triển nhị thức:
Sau khi lấy modulo \(p\), trong \(F_{2p}\) chỉ còn hạng \(\dbinom{2p}{p}\equiv 2 \pmod p\); trong \(F_{2p+1}\) còn các hạng \(\dbinom{2p+1}{1}\equiv 1 \pmod p\)、\(\dbinom{2p+1}{p}\equiv 2 \pmod p\)、\(\dbinom{2p+1}{2p+1}\equiv 1 \pmod p\).
Vậy \(F_{2p}\) và \(F_{2p+1}\) trùng với \(F_{-2}\) và \(F_{-1}\), nên \(2p+2\) là chu kỳ.
Kết luận 3: Với nguyên tố \(p\), \(M\) là chu kỳ của Fibonacci modulo \(p^{k-1}\) khi và chỉ khi \(Mp\) là chu kỳ modulo \(p^k\). Đặc biệt, chu kỳ Pisano cũng tương đương theo quy tắc này.
Chứng minh:
Ở đây coi \(\frac{1+\sqrt{5}}{2}\) là một phần tử.
Do:
Suy ra:
Do chiều ngược cũng suy ra, nên \(M\) là chu kỳ modulo \(p^{k-1}\) iff:
Với \(p\) nguyên tố lẻ, dùng bổ đề nâng lũy thừa:
Với \(p=2\), dùng:
Thay \(a\) là \(\left(\frac{1+\sqrt{5}}{2}\right)\) và \(\left(\frac{1-\sqrt{5}}{2}\right)\), \(t\) là \(M\) và \(Mp\), ta được điều kiện tương đương:
Vậy \(Mp\) là chu kỳ modulo \(p^k\). Do chu kỳ tương đương nên chu kỳ nhỏ nhất cũng tương đương.
Ba kết luận xong. Mã:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | |
Bài tập
- SPOJ - Euclid Algorithm Revisited
- SPOJ - Fibonacci Sum
- HackerRank - Is Fibo
- Project Euler - Even Fibonacci numbers
-
Trang này chủ yếu dịch từ bài Числа Фибоначчи và bản tiếng Anh Fibonacci Numbers. Bản Nga: Public Domain + Leave a Link; bản Anh: CC-BY-SA 4.0.
Last updated on this page:, Update history
Found an error? Want to help improve? Edit this page on GitHub!
Contributors to this page:OI-wiki
All content on this page is provided under the terms of the CC BY-SA 4.0 and SATA license, additional terms may apply