做法来自jianglangcaijin
Problem
求
Solution
实在没看出扩展在哪。。和Lucas有任何相似之处吗。。。 看了很久才看懂啊。。。太弱了。 首先,如果可以分别求出来,用中国剩余定理就可以地解出来了。 现在的问题是要求。 而 而有关于的逆元,当且仅当 所以要把除以分母变成乘它的逆元,必须先把分母中的含有的的幂先处理掉。 现在单独看的话
以为例
把的倍数提出来,就是
分别考虑这些项
递归处理
的值是循环的,每一段区间的乘积是相等的(不会证明啊。。求证明啊。。),于是就可以循环部分用快速幂,超出循环的部分直接累乘。
而就是需要处理掉的部分,每一层递归的累乘起来就是在出现的所有了。
可以直接整体地把的质因子分解中的次数求出来,把从阶乘中提出来,就可以消除其影响了。
于是就得到了上面问题的解决方法:
把中的次数分别求出来,而这个是比较好求的。幂的相除相当于指数相减,所以中包含的的次数为。消除了的影响,对剩下的两项递归求解即可。
呃虽然好求我也是看了一会儿才懂。。
1
for(int i=n;i;i/=p) res+=i/p;
直观地感受一下,当时,求的是之内有多少个数字的是的倍数,相当于把以内的数集体,这样只含的数字就被干掉了,剩下的数字继续进行这个过程。
Code
1 | //Code by Lucida |
貌似跑得很慢。应该还有更优的做法。待进一步研究。 学习了一下别人的写法,学到了这些
小小的优化
- 对的值打表。
- 如果算出来的比当前需要算的(即模数的指数)还大,直接返回0。
彻底改进
对于每个数质因子,预处理
上面的很多东西就查表即可。见Code。
Modified Code
1 | //Code by Lucida |