【问题标题】:Calculated nCr mod m (n choose r) for large values of n (10^9)为较大的 n (10^9) 值计算 nCr mod m (n 选择 r)
【发布时间】:2015-05-03 01:24:59
【问题描述】:

现在 CodeSprint 3 已经结束,我一直在想如何解决这个问题。对于较大的 r 和 n (0

【问题讨论】:

    标签: modulo ncr


    【解决方案1】:

    对于非素数模,分解它 (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) mod 11 = 1
    • C(234, 44) mod 13 = 0
    • C(234, 44) mod 37 = 16

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

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

    结果是 x = 6084。

    示例

    C(234, 44) mod 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
    

    现在创建通用 Lucas 所需的阶乘函数

    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

    【讨论】:

    • 您能解释一下如何使用通用卢卡斯定理计算 C(n, k) mod p^q?
    • 我做了一个例子,还是你想要伪代码?其中大部分依赖于扩展欧几里得的实现,以获得 GCD 以简化阶乘并执行求解线性同余和使用中国剩余定理组合所需的模逆
    • 这更好,但我真的不明白它为什么有效,除了试图盲目地复制论文中描述的内容并希望它有效。我了解扩展欧几里得、模逆和 CRT,以及卢卡斯定理的原始版本,但对扩展版本为何正确以及相应算法如何工作(即,我们为什么要期望它给出一个正确的结果?)。
    • 为什么你刚才说 s 是 -1 ?我刚刚阅读了广义的卢卡斯定理。它有一种力量,e_q-1。
    • 顺便说一下,我认为在基数 p 中添加 a 和 b 时携带的数字与 (a+b)Cb 中的幂 p 的数量相同。我说的对吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-06
    • 2012-04-24
    • 1970-01-01
    • 2014-07-13
    • 1970-01-01
    相关资源
    最近更新 更多