Compute nCr % p

Difficulty Level Easy
Frequently asked in Accenture Cadence India Komli Media Ola Cabs Square
Dynamic Programming MathViews 1492

Problem Statement

The problem “Compute nCr % p” states that you are required to find binomial coefficient modulo p. So you first must know about the binomial coefficient. We have already discussed that in a previous post. You can check that here.

Example

n = 5, r = 2, p = 6
4

Explanation

nCr = 5C2 = 10
nCr % p = 10%6 = 4
So, we calculated 5C2 using the formula of the binomial coefficient. Then took the modulo over the value.

Compute nCr % p

Approach

In the previous post regarding the calculation of the binomial coefficient. What we did was first computed the values which were required to solve nCr. We used dynamic programming to solve the problem but then we were only calculating the value of nCr. Not the binomial coefficient modulo some number p. The naive approach would be to first calculate the binomial coefficient and then take the modulo p. But there is a limitation on this calculation. You can’t calculate Binomial coefficients for large numbers as that will result in an overflow. So we need to find a way that can produce a correct result without going into integer overflow.

One thing that we can do is keep on taking modulus while the calculation of our binomial coefficient. So the only change form the solution of previous post is that we will take modulus during the calculations. Thus our recursive formula will change a bit, but the transitions remain the same. And the current binomial coefficient is dependent on the same states as it was previously.

Code

C++ code to compute nCr % p

#include<bits/stdc++.h>
using namespace std;
// this function just makes our pascal triangle
int computeBinomialCoefficientsModuloP(int n, int r, int p)
{
  int C[r+1];
    C[0] = 1;
    for (int i = 0; i <= n; i++)
    {
        // since the recursive formula is dependent on current and previous binomial coefficient on i
        // if we had run a forward loop our algorithm would have not given us a correct result
        for (int j = min(i, r); j >0 ; j--)
        {
            C[j] = (C[j - 1] + C[j])%p; // use recursive formula
        }
    }
    return C[r];
}

int main()
{
    int n,k,p;cin>>n>>k>>p;
    // here n & k do not satisfy the properties of binomial coefficient
    // then we will answer it as 0
    int val = computeBinomialCoefficientsModuloP(n, k, p);
    if(val != 0)
      cout<<val<<endl;
    else
      cout<<0<<endl;
}
5 2 4
2

Java code to compute nCr % p

import java.util.*;
class Main{
  // this function just makes our pascal triangle
  static int computeBinomialCoefficientsModuloP(int n, int r, int p) 
  {
  	int C[] = new int[r+1];
  	C[0] = 1;
    for (int i = 0; i <= n; i++) 
    { 
      // since the recursive formula is dependent on current and previous binomial coefficient on i
      // if we had run a forward loop our algorithm would have not given us a correct result 
      for (int j = Math.min(i, r); j >0 ; j--) 
      {
          C[j] = (C[j - 1] + C[j])%p; // use recursive formula
      }
    } 
    return C[r]; 
  }
  
  public static void main(String[] args)
  {
      Scanner sc = new Scanner(System.in);
      // here n & k do not satisfy the propertoes of binomial coefficient
      // then we will answer it as 0
      int n = sc.nextInt();
      int k = sc.nextInt();
      int p = sc.nextInt();
      int val = computeBinomialCoefficientsModuloP(n, k, p);
      if(val != 0)
        System.out.println(val);    
      else
        System.out.println(0);
   }
}
5 2 4
2

Complexity Analysis

Time Complexity

O(N*R), where N and R are the inputs given. This is because when we were calculating our Binomial Coefficient, we had an outer loop and one inner loop.

Space Complexity

O(R), since we made an array to store the intermediate values, and thus the space complexity is linear.

Translate ยป