Compute nCr % p | Set 3 (Using Fermat Little Theorem) - GeeksforGeeks

25 Jun, 2021
Given three numbers n, r and p, compute the value of nCr mod p. Here p is a prime number greater than n. Here nCr is Binomial Coefficient.Example: 
Input:  n = 10, r = 2, p = 13
Output: 6
Explanation: 10C2 is 45 and 45 % 13 is 6.

Input:  n = 6, r = 2, p = 13
Output: 2
We have discussed the following methods in previous posts. Compute nCr % p | Set 1 (Introduction and Dynamic Programming Solution) Compute nCr % p | Set 2 (Lucas Theorem)In this post, Fermat Theorem-based solution is discussed.Background: Fermat’s little theorem and modular inverse Fermat’s little theorem states that if p is a prime number, then for any integer a, the number ap – a is an integer multiple of p. In the notation of modular arithmetic, this is expressed as: ap = a (mod p) For example, if a = 2 and p = 7, 27 = 128, and 128 – 2 = 7 × 18 is an integer multiple of 7.If a is not divisible by p, Fermat’s little theorem is equivalent to the statement a p – 1 – 1 is an integer multiple of p, i.e ap-1 = 1 (mod p)If we multiply both sides by a-1, we get. ap-2 = a-1 (mod p)So we can find modular inverse as p-2. Computation: 
We know the formula for  nCr 
nCr = fact(n) / (fact(r) x fact(n-r)) 
Here fact() means factorial.

 nCr % p = (fac[n]* modIverse(fac[r]) % p *
               modIverse(fac[n-r]) % p) % p;
Here modIverse() means modular inverse under
modulo p.
Following is the implementation of the above algorithm. In the following implementation, an array fac[] is used to store all the computed factorial values. 
C++
Java
Python3
C#
PHP
Javascript
// A modular inverse based solution to// compute nCr % p#include <bits/stdc++.h>using namespace std; /* Iterative Function to calculate (x^y)%pin O(log y) */unsigned long long power(unsigned long long x,                                  int y, int p){    unsigned long long res = 1; // Initialize result     x = x % p; // Update x if it is more than or    // equal to p     while (y > 0)    {             // If y is odd, multiply x with result        if (y & 1)            res = (res * x) % p;         // y must be even now        y = y >> 1; // y = y/2        x = (x * x) % p;    }    return res;} // Returns n^(-1) mod punsigned long long modInverse(unsigned long long n,                                             int p){    return power(n, p - 2, p);} // Returns nCr % p using Fermat's little// theorem.unsigned long long nCrModPFermat(unsigned long long n,                                 int r, int p){    // If n<r, then nCr should return 0    if (n < r)        return 0;    // Base case    if (r == 0)        return 1;     // Fill factorial array so that we    // can find all factorial of r, n    // and n-r    unsigned long long fac[n + 1];    fac[0] = 1;    for (int i = 1; i <= n; i++)        fac[i] = (fac[i - 1] * i) % p;     return (fac[n] * modInverse(fac[r], p) % p            * modInverse(fac[n - r], p) % p)           % p;} // Driver programint main(){    // p must be a prime greater than n.    int n = 10, r = 2, p = 13;    cout << "Value of nCr % p is "         << nCrModPFermat(n, r, p);    return 0;}
// A modular inverse based solution to// compute nCr %import java.io.*; class GFG {     /* Iterative Function to calculate    (x^y)%p in O(log y) */    static int power(int x, int y, int p)    {         // Initialize result        int res = 1;         // Update x if it is more than or        // equal to p        x = x % p;         while (y > 0) {             // If y is odd, multiply x            // with result            if (y % 2 == 1)                res = (res * x) % p;             // y must be even now            y = y >> 1; // y = y/2            x = (x * x) % p;        }         return res;    }     // Returns n^(-1) mod p    static int modInverse(int n, int p)    {        return power(n, p - 2, p);    }     // Returns nCr % p using Fermat's    // little theorem.    static int nCrModPFermat(int n, int r,                             int p)    {           if (n<r)              return 0;      // Base case        if (r == 0)            return 1;         // Fill factorial array so that we        // can find all factorial of r, n        // and n-r        int[] fac = new int[n + 1];        fac[0] = 1;         for (int i = 1; i <= n; i++)            fac[i] = fac[i - 1] * i % p;         return (fac[n] * modInverse(fac[r], p)                % p * modInverse(fac[n - r], p)                % p)            % p;    }     // Driver program    public static void main(String[] args)    {         // p must be a prime greater than n.        int n = 10, r = 2, p = 13;        System.out.println("Value of nCr % p is "                           + nCrModPFermat(n, r, p));    }} // This code is contributed by Anuj_67.
# Python3 function to# calculate nCr % pdef ncr(n, r, p):    # initialize numerator    # and denominator    num = den = 1    for i in range(r):        num = (num * (n - i)) % p        den = (den * (i + 1)) % p    return (num * pow(den,            p - 2, p)) % p # p must be a prime# greater than nn, r, p = 10, 11, 13print("Value of nCr % p is",               ncr(n, r, p))
// A modular inverse based solution to// compute nCr % pusing System; class GFG {     /* Iterative Function to calculate    (x^y)%p in O(log y) */    static int power(int x, int y, int p)    {         // Initialize result        int res = 1;         // Update x if it is more than or        // equal to p        x = x % p;         while (y > 0) {             // If y is odd, multiply x            // with result            if (y % 2 == 1)                res = (res * x) % p;             // y must be even now            y = y >> 1; // y = y/2            x = (x * x) % p;        }         return res;    }     // Returns n^(-1) mod p    static int modInverse(int n, int p)    {        return power(n, p - 2, p);    }     // Returns nCr % p using Fermat's    // little theorem.    static int nCrModPFermat(int n, int r,                             int p)    {       if (n<r)            return 0;      // Base case        if (r == 0)            return 1;         // Fill factorial array so that we        // can find all factorial of r, n        // and n-r        int[] fac = new int[n + 1];        fac[0] = 1;         for (int i = 1; i <= n; i++)            fac[i] = fac[i - 1] * i % p;         return (fac[n] * modInverse(fac[r], p)                % p * modInverse(fac[n - r], p)                % p)            % p;    }     // Driver program    static void Main()    {         // p must be a prime greater than n.        int n = 10, r = 11, p = 13;        Console.Write("Value of nCr % p is "                      + nCrModPFermat(n, r, p));    }} // This code is contributed by Anuj_67
<?php// A modular inverse// based solution to// compute nCr % p // Iterative Function to// calculate (x^y)%p// in O(log y)function power($x, $y, $p){         // Initialize result    $res = 1;     // Update x if it    // is more than or    // equal to p    $x = $x % $p;     while ($y > 0)    {                 // If y is odd,        // multiply x        // with result        if ($y & 1)            $res = ($res * $x) % $p;         // y must be        // even now        // y = y/2        $y = $y >> 1;        $x = ($x * $x) % $p;    }    return $res;} // Returns n^(-1) mod pfunction modInverse($n, $p){    return power($n, $p - 2, $p);} // Returns nCr % p using// Fermat's little// theorem.function nCrModPFermat($n, $r, $p){         if ($n<$r)          return 0;      // Base case    if ($r==0)        return 1;     // Fill factorial array so that we    // can find all factorial of r, n    // and n-r    //$fac[$n+1];    $fac[0] = 1;    for ($i = 1; $i <= $n; $i++)        $fac[$i] = $fac[$i - 1] *                        $i % $p;     return ($fac[$n] * modInverse($fac[$r], $p) % $p *             modInverse($fac[$n - $r], $p) % $p) % $p;}     // Driver Code    // p must be a prime    // greater than n.    $n = 10;    $r = 2;    $p = 13;    echo "Value of nCr % p is ",         nCrModPFermat($n, $r, $p);         // This code is contributed by Ajit.?>
<script>     // A modular inverse based solution    // to compute nCr % p         /* Iterative Function to calculate    (x^y)%p in O(log y) */    function power(x, y, p)    {          // Initialize result        let res = 1;          // Update x if it is more than or        // equal to p        x = x % p;          while (y > 0) {              // If y is odd, multiply x            // with result            if (y % 2 == 1)                res = (res * x) % p;              // y must be even now            y = y >> 1; // y = y/2            x = (x * x) % p;        }          return res;    }      // Returns n^(-1) mod p    function modInverse(n, p)    {        return power(n, p - 2, p);    }      // Returns nCr % p using Fermat's    // little theorem.    function nCrModPFermat(n, r, p)    {        if (n<r)      {          return 0;      }               // Base case      if (r == 0)        return 1;       // Fill factorial array so that we      // can find all factorial of r, n      // and n-r      let fac = new Array(n + 1);      fac[0] = 1;       for (let i = 1; i <= n; i++)        fac[i] = fac[i - 1] * i % p;       return (fac[n] * modInverse(fac[r], p) % p *              modInverse(fac[n - r], p) % p) % p;    }         // p must be a prime greater than n.    let n = 10, r = 2, p = 13;    document.write("Value of nCr % p is " +                    nCrModPFermat(n, r, p)); </script>
Value of nCr % p is 6
 
Improvements: In competitive programming, we can pre-compute fac[] for given upper limit so that we don’t have to compute it for every test case. We also can use unsigned long long int everywhere to avoid overflows.This article is contributed by Nikhil Papisetty. If you like GeeksforGeeks and would like to contribute, you can also write an article using write.geeksforgeeks.org or mail your article to review-team@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above.
jit_t
vt_m
HemanthSai1
mohdnazarkashif
mukesh07
simmytarika5
surindertarika1234
binomial coefficient
factorial
Modular Arithmetic
number-theory
Mathematical
number-theory
Mathematical
Modular Arithmetic
factorial
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.
Merge two sorted arrays
Modulo Operator (%) in C/C++ with Examples
Program to find GCD or HCF of two numbers
Prime Numbers
Program to find sum of elements in a given array
Program for Decimal to Binary Conversion
Sieve of Eratosthenes
Program for factorial of a number
Operators in C / C++
Euclidean algorithms (Basic and Extended)