gpt4 book ai didi

modulo - 对于较大的 n 值 (10^9) 计算 nCr mod m(n 选择 r)

转载 作者:行者123 更新时间:2023-12-02 12:17:59 25 4
gpt4 key购买 nike

现在 CodeSprint 3 已经结束了,我一直在想如何解决这个问题。对于较大的 r 和 n 值(0<=n<=10^9;0<=r<=n),我们需要简单地计算 nCr mod 142857。我使用了递归方法,该方法经过 min(r, n-r) 次迭代来计算组合。事实证明这不够有效。我尝试了几种不同的方法,但它们似乎都不够有效。有什么建议吗?

最佳答案

对于非素数模,将其分解 (142857 = 3^3 * 11 * 13 * 37) 并使用一般卢卡斯定理计算该模的每个素数因子的 C(n,k) mod p^q,并且使用中国剩余定理将它们结合起来。

例如,C(234, 44) mod 142857 = 6084,则

  • C(234, 44) mod 3^3 = 9
  • C(234, 44) 模 11 = 1
  • C(234, 44) 模 13 = 0
  • C(234, 44) mod 37 = 16

中国剩余定理涉及找到 x 使得

  • x = 9 mod 3^3
  • x = 1 mod 11
  • x = 0 模 13
  • x = 16 mod 37

结果是 x = 6084。

示例

C(234, 44) 模 3^3

首先将 n、k 和 n-k 转换为基数 p

n = 234_10 = 22200_3

k = 44_10 = 1122_3

r = n-k = 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

现在创建一般卢卡斯所需的阶乘函数

def f(n, p):
r = 1
for i in range(1, n+1):
if i % p != 0:
r *= i
return r

由于 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

现在

s = 1 if p = 2 and q >= 3 else -1

然后

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

现在你有了

-60474102975 / 7 mod 3^3

这是一个线性同余,可以用以下方法解决

ModularInverse(7, 3^3) = 4
4 * -60474102975 mod 27 = 9

因此 C(234, 44) mod 3^3 = 9

关于modulo - 对于较大的 n 值 (10^9) 计算 nCr mod m(n 选择 r),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13146654/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com