摘要
一种能在模数较小时
O(lognlogpn) 求出
n! 的算法。
实现
我们知道:
(⌊2n⌋n)=⌊2n⌋!⌈2n⌉!n!
所以:
n!=(⌊2n⌋n)⌊2n⌋!⌈2n⌉!
后面的
⌊2n⌋!⌈2n⌉! 可以根据
n 的奇偶性化为
(⌊2n⌋!)2 或
(⌊2n⌋!)2⌈2n⌉。
这个是可以递归计算的。
而前面的
(⌊2n⌋n) 一般情况下并没有什么好的计算方法,但我们可以使用 Lucas 定理在模数较小的情况下在
O(logpn) 的时间内求出它的值。
时间复杂度分析
至多递归
O(logn) 层,每层使用 Lucas 定理是
O(logpn) 的,所以总复杂度是
O(lognlogpn) 的。
前途
相比于休闲娱乐区前几篇光速阶乘算法,这个方法具有可行性且实际优化了复杂度。
相比于传统的快速阶乘算法的
O(nlogn),这个方法更快,在
p=104+7 时,我们也可以在可接受的时间内计算出
n=1018 时
n!modp 的值。