如何计算大数阶乘数的最后几个非零数字?
大,我的意思是n = 10 ^ 100或者什么 (编辑:10 ^ 100是n中的' n!)的数量。 很少,我的意思是直到7-8 ......
我尝试使用Google搜索并找到了这个 -
Last non-zero digit of a factorial
我尝试将此扩展为最后2个非零数字或更多,但失败了......
我发现谷歌上的其他网站显示了如何计算最后x位数,但它不清楚,我无法理解它...
任何人都可以帮我吗?
另外,我无法得到这个,99的最后两个非零数字!是64,所以我认为(199!/ 99!)的最后两个非零数字也应该是64,但它们结果是24,我知道我做的非常大在这一个的逻辑错误,我只是无法把手指放在它上面!
答案 0 :(得分:9)
进行计算的技巧是你要找到3个数字。
5的因子数给出10的因子数。然后从5的因子数中减去2的因子数。计算出该幂的2的最后几位数。将其乘以步骤3中的最后几位数字,即可完成。
5的因子数可以如下计算。取n / 5(向下舍入)。那是多少人的第一个因子为5.然后是n / 25(向下舍入)。有多少人有第二个因子5.继续,直到你完成。
2的因子数量可以类似地仅用序列2,4,8,16来计算。
第三部分很棘手。
但更容易做的是弄清楚所有数字的乘积,包括n
,它们是2和5的相对素数。调用该函数f(n)
。你可以通过乘以相对质数mod 10 ^ k来计算它。并利用f(i * 10^k + j) = f(j) mod(10^k)
。
然后你想要f(n)*f(n/2)*f(n/4)*f(n/5)*f(n/8)*f(n/10)*f(n/16)*...
的最后几位数字。有效地生成该序列是汉明数字问题的一个版本。有关如何执行此操作,请参阅https://rosettacode.org/wiki/Hamming_numbers。对于10 ^ 100,在这个序列中仍然只有数万个 - 它完全受到控制。
关于比率的第二个问题,您需要利用以下两个事实。事实1是你通过减法知道2和5的正确数量因子。第二个是,如果m
相对于10
是素数,那么m * m^(4 * 10^(k-1) - 1)
就是1 mod 10^k
。所以你现在可以"划分" mod 10 ^ k,并找出答案的每个因素的最后几个项,它们不涉及2或5,然后计算出0的数量,以及2或5的剩余因子的数量你有。
这是一项重要的优化。如果你知道f(n)
mod 2 ^ 8和5 ^ 8,那么很难弄清楚mod 10 ^ 8。但它的值mod这两个可以简化为适度大小的查找表。较大的一个你只需要将它存储到奇数n最多4 * 390625,但是那些不到800k。 (此时你将乘以不能被5 mod 5 ^ 8整除的事物组合中的所有元素,并且该乘积为1.然后重复模式。)如果你使用4字节整数,那个可以很容易预先计算的MB查找表。
我应该解释为什么这个技巧有效,因为它并不明显,我错了几次。诀窍是相对于5 ^ k的数字形成一个组。意思是每个都有一个逆。因此,如果将它们全部相乘并重新排列,则每个都具有反向超出5 ^ k-1。所以乘以另一个副本再次配对,包括那个讨厌的产品和产品出来1.现在对于我们的f我们只对5不能被5整除的奇数不感兴趣,但奇数不能被5到2 *整除5 ^ k,mod 5 ^ k,只是可以被5到5 ^ k整除的那些的重新排列。我们需要2份,因此需要4 * 5 ^ k。但是我们只需要几率,因为偶数之后总是和前一个奇数相同。
根据请求,以下是单个示例的工作原理。我将完成15的最后3位数字。
15! = 1 * 2 * 3 * 4 * 5 * 6 * 7 * 8 * 9 * 10 * 11 * 12 * 13 * 14 * 15
= (1*3*7*9*11*13) * (2*6*14) * (4*12) * (5*15) * (8) * (10)
= (1*3*7*9*11*13) * 2^3*(1*3*7) * 2^4*(1*3) * 5^2*(1*3) * 2^3*(1) * 10*(1)
= 2^11 * 5^3 * f(15) * f(15/2) * f(15/4) * f(15/5) * f(15/8) * f(15/10)
= 2^11 * 5^3 * f(15) * f(15/2) * f(15/4) * f(15/5) * f(15/8) * f(15/10)
= 10^3 * 2^8 * f(15) * f(7) * f(3) * f(3) * f(1) * f(1)
Which leads to the calculation...
256 * 27 * 21 * 3 * 3 * 1 * 1 (mod 1000)
= 368 (mod 1000)
这是正确的,因为15! = 1307674368000
。