2015-04-04 4 views
4

Я пытаюсь вычислить nCr по модулю p, где p - простое число.Вычисление nCr по модулю p, простое

Один из подходов, который я пробовал, - это вычислить n!/(r! * (n-r)!) по модулю p с использованием мультипликативных обратных, но это не удается, если либо r, либо n - r больше или равно p, так как тогда факториалы равны нулю по модулю p, а обратные не существуют.

Какой метод работает во всех случаях, а не только при наличии мультипликативных инверсий?

+0

«Этот алгоритм даст nCr = 0 для каждого n, большего чем p, так как mod factorial станет равным нулю. Но это неправильный расчет. Ex. 14C1 mod 13 = 1, а не 0. «Как вы получаете 0 с помощью вашего алгоритма? – IVlad

+0

' f [n] * ((InverseEuler (f [r], p) * InverseEuler (f [nr], p))% p))% p', где 'f [n] (n!% p)' и InverseEuler (a, b) есть '((a^(p-2))% p)'. Это была бы дискретная формула для nCr, используя теорему Эйлера для модулярного мультипликативного обратного. f [n] при n> = p будет равна нулю, и, следовательно, значение nCr станет равным нулю. Исправьте меня, если я ошибаюсь. @IVlad – Ashwini

+0

Эта формула работает только для 'f [x], p' coprime. Умножения 'p' не являются взаимно простыми с' p'. – IVlad

ответ

7

Я бы использовать Lucas's theorem

C(14,1), p=13 
N = 14 = 1 * 13 + 1 
K = 1 = 0 * 13 + 1 
C(N,K) mod p = (C(1,0) mod 13) * (C(1,1) mod 13) = 1 
+0

Это то, что мне нужно .... .thanks много @MBo – Ashwini

0

Вычисление Ncr по модулю р, р простое число

  1. предварительно вычислить факториал п по модулю р с помощью
    факт [N] = п * факт [n-1]% p
  2. предварительно вычислить обратный факторный номер n по модулю p, используя
    invfact [п] = modular_inverse (п) * Infact [п-1]% р

    modular_inverse может быть легко обнаруживается с помощью Fermat's little theorem или Extended Euclidean algorithm. (В р простое число, оба могут быть использованы)
  3. Получить Ncr многосвязными фактом [п] * Infact [г] * Infact [NR]% р

Другой метод: Вы также можете использовать паскаль метод для расчета Ncr

Как для любого Ncr, вы можете использовать

row[0]=1; 
for(i=1;i<n/2;i++) 
{ 
    row[i]=row[i-1]*(n-i+1)/i 
} 

for(i=n/2;i<=n;i++) 
{ 
    row[i]=row[n-i] 
} 

В этом вы должны принять modulo_inverse из (I) с использованием любого из выше способом (Fermat's little theorem или Extended Euclidean algorithm)

порядковый номер: Best known algos for calculating nCr % M

Смежные вопросы