现在CodeSprint 3已经结束了,我一直想知道如何解决这个问题.对于r和n的大值,我们需要简单地计算nCr mod 142857(0 <= n <= 10 ^ 9; 0 <= r <= n).我使用递归方法,通过min(r,nr)迭代来计算组合.结果证明这不够有效.我尝试过几种不同的方法,但它们似乎都不够高效.有什么建议?
对于非素数mod,使用一般Lucas定理对因子(142857 = 3 ^ 3*11*13*37)进行因子并计算模型的每个素因子的C(n,k)mod p ^ q,并使用它们组合它们中国剩余定理.
例如,C(234,44)mod 142857 = 6084,然后
中国剩余定理涉及找到x这样的
结果是x = 6084.
C(234,44)mod 3 ^ 3
首先将n,k和nk转换为基数p
n = 234_10 = 22200_3
k = 44_10 = 1122_3
r = nk = 190_10 = 21001_3
接下来找到承载的数量
e[i] = number of carries from i to end
e 4 3 2 1 0
1 1
r 2 1 0 0 1
k 1 1 2 2
n 2 2 2 0 0
Run Code Online (Sandbox Code Playgroud)
现在创建一般卢卡斯所需的阶乘函数
def f(n, p):
r = 1
for i in range(1, n+1):
if i % p != 0:
r *= i
return r
Run Code Online (Sandbox Code Playgroud)
由于q = 3,您一次只能考虑基本p表示的三个数字
所以
f(222_3, 3)/[f(210_3, 3) * f(011_3, 3)] *
f(220_3, 3)/[f(100_3, 3) * f(112_3, 3)] *
f(200_3, 3)/[f(001_3, 3) * f(122_3, 3)] = 6719344775 / 7
Run Code Online (Sandbox Code Playgroud)
现在
s = 1 if p = 2 and q >= 3 else -1
Run Code Online (Sandbox Code Playgroud)
然后
p^e[0] * s * 6719344775 / 7 mod 3^3
e[0] = 2
p^e[0] = 3^2 = 9
s = -1
p^e[0] * s * 6719344775 = -60474102975
Run Code Online (Sandbox Code Playgroud)
现在你有了
-60474102975 / 7 mod 3^3
Run Code Online (Sandbox Code Playgroud)
这是一个线性同余,可以解决
ModularInverse(7, 3^3) = 4
4 * -60474102975 mod 27 = 9
Run Code Online (Sandbox Code Playgroud)
因此C(234,44)mod 3 ^ 3 = 9