求斐波那契数列第 n 项详解
作者:互联网
看到这篇文章的标题,你可能会觉得它对新手非常友好。
可惜你只对了一半。这篇文章不是给萌新看的,但是萌新也能轻松看懂。
问题描述
求斐波那契数列的第 n n n 项。
题1
限制:
1
≤
n
≤
1
0
8
1 \le n \le 10^8
1≤n≤108
解法: 很好,直接暴力递推就行了。
题2
限制:
1
≤
n
≤
1
0
18
1 \le n \le 10^{18}
1≤n≤1018,要对
1
0
9
+
7
10^9+7
109+7 取模。
解法: 很好,直接矩阵快速幂就行了。
题3
限制:
1
≤
n
≤
1
0
30000000
1 \le n \le 10^{30000000}
1≤n≤1030000000,模数为
1
0
8
−
5
10^8-5
108−5 。
解法
考虑斐波那契数列的通项为
F
n
=
1
5
(
(
1
+
5
)
n
2
−
(
1
−
5
)
n
2
)
F_n=\frac {1} {\sqrt 5}(\frac {(1+\sqrt 5)^n} {2}-\frac {(1-\sqrt 5)^n} {2})
Fn=5
1(2(1+5
)n−2(1−5
)n)
由于 5 \sqrt 5 5 在模 1 0 8 − 5 10^8-5 108−5 意义下的值为 1 0 4 10^4 104 ,所以直接把 1 0 4 10^4 104 带进去算就行了。
时间复杂度 O ( log n ) O(\log n) O(logn) ,去掉了快速幂的那个 8 8 8 的常数。
题4
限制: 1 ≤ n ≤ 1 0 40000000 1 \le n \le 10^{40000000} 1≤n≤1040000000,模数为 m ( 1 ≤ m ≤ 2 31 − 1 ) m(1 \le m \le 2^{31}-1) m(1≤m≤231−1) 。
解法2
Lemma
斐波那契数列在模意义下是有循环节的,循环节长度不超过模数的 6 6 6 倍。并且只有当 m = 2 × 5 p m=2 \times 5^p m=2×5p 的时候才取到等号。
由于循环节的长度并不大, 我们可以考虑一个随机化算法,
我们每次在区间 [ 1 , 18 × m o d ] [1,18 \times mod] [1,18×mod] 中等概率挑出一个之前从来没有被选择过的数 i i i ,并用矩阵快速幂求出 F i , F i + 1 F_i,F_{i+1} Fi,Fi+1 在模意义下的值,再将 ( i , F i , F i + 1 ) (i,F_i,F_{i+1}) (i,Fi,Fi+1) 这个三元组存在一个哈希表中。如果产生了 ⌊ \lfloor ⌊ 哈希冲突 ⌉ \rceil ⌉,那么立即退出,并宣布已经找到一个循环节。
找到循环节之后就可以将 n n n 对循环节长度取模,从而大大减小了 n n n ,于是就可以愉快地矩阵快速幂啦。
根据生日悖论,期望在 m \sqrt m m 次找到循环节。于是时间复杂度为 O ( m log m ) O(\sqrt m \log m) O(m logm)
可以通过。
标签:10,le,log,18,sqrt,求斐波,那契,详解 来源: https://blog.csdn.net/Cherrt/article/details/113795190