欢迎使用CSDN-markdown编辑器

本篇文章的基础请 先看这里

先将N中5的倍数用1代替,然后每10个分成一组,也许你要问10个一组怎么看出来的?因为只求最后一位,而每10个最后的尾数相同,一开始也没有想到,参考网上的例子才想到,这样就分成了N/10 这里的除法是整除,那么在不算上5的倍数的基础上得到
1. X[N] = data[N] 当N < 10
2. X[N] = data[N%10] * 6 当N >= 10
X[N]即代表尾数
data[10] ={1, 1, 2, 6, 4, 4, 4, 8, 4, 6};
data分别为0到9的阶乘最后一个不为0的位,将5的倍数的地方用1代替。

X[N] = data[N%10] * 6 当N >= 10
为什么要乘以6 其实准确的来讲不是乘以6而是 6^(N/10)但是6*6 最后一位还是6 所以可以写成乘以6
还有一个就是只要N>1以后都是偶数,而偶数的结尾是一定是2,4,6,8 为什么没有0 因为5的倍数,都被剔除了,而6乘以2,4,6,8之后还是2,4,6,8.
也就是说,N>2之后,我可以在总的后面乘以6对结果没有影响

然后再来看5的倍数那一部分,它们是:5*10 * 15 * 20 * 25 * 30 * 35
我们发现将他们提取公因子,可以写成 5^P * P!。其中P = [N/5],因为求得是阶乘最后一位非零位,所以这里的5^P必须要用P个2来匹配掉,如果将最后的非零位记为T[N]的话,那么T[N] = (X[N] / 2^P) * T[P]; 这里的除法不是不同意义的除法,因为X[N]有可能是1位数,我们发现:
2^1 % 10 = 2,
2^2 % 10 = 4,
2^3 % 10 = 8,
2^4 % 10 = 6,

每四个一循环,当P == 0的时候比较特殊,2^P % 10 = 1
除上2^P其实就是乘上2^(-P),这样处理就简单了,根据循环的性质就可以将T[N]简化成T[N] = X[N] * 2^(-P) * T[P],这样一来,算法的复杂度就只有O(log5(N))了。并且2是每四个一循环,2^(-P) = 2^(-P % 4 + 4)。 计算T[N]只需要递归计算T[N/5]即可。

那么
0 - 4 的时候要除以 2^0 = 1
5 - 9 的时候要除以 2^1 = 2
10 - 14 的时候要除以 2^2 = 4
15 - 19 的时候要除以 2^3 = 8
20 - 24 的时候要除以 2^4 = 6

又因为我说过乘以6没有影响 所以我在20-24的时候乘以一个6 那么就相当于20-24的时候我乘以一个6再除以一个6 等于除以一个1

那么此时就循环了 一个的循环节是4 一个循环节是10 所以循环节为20

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值