2

I want to calculate combinations C(n, k) where n and k could be very large. I tried to do so by using modular inverse as following, but it's not giving correct output even for small numbers. Can anybody tell me where I'm wrong?

import java.math.BigInteger;

public class Test {

    public static int[] factorials = new int[100001];
    public static int mod = 1000000007;
    public static BigInteger MOD = BigInteger.valueOf(1000000007);

    public static void calculateFactorials() {

        long f = 1;

        for (int i = 1; i < factorials.length; i++) {
            f = (f * i) % mod;
            factorials[i] = (int) f;
        }

    }

    // Choose(n, k) = n! / (k! * (n-k)!)
    public static long nCk(int n, int k) {

        if (n < k) {
            return 0;
        }

        long a = BigInteger.valueOf(k).modInverse(MOD).longValue();
        long b = BigInteger.valueOf(n - k).modInverse(MOD).longValue();

        // Left to right associativity between * and %
        return factorials[n] * a % mod * b % mod;

    }

    public static void main(String[] args) {

        calculateFactorials();
        System.out.println(nCk(5, 2));

    }

}
Ry-
  • 218,210
  • 55
  • 464
  • 476
Hitesh Dholaria
  • 157
  • 3
  • 13

1 Answers1

3

The lines

    long a = BigInteger.valueOf(k).modInverse(MOD).longValue();
    long b = BigInteger.valueOf(n - k).modInverse(MOD).longValue();

should be

    long a = BigInteger.valueOf(factorials[k]).modInverse(MOD).longValue();
    long b = BigInteger.valueOf(factorials[n - k]).modInverse(MOD).longValue();

You might consider caching the inverse factorials as well as the factorials.

David Eisenstat
  • 64,237
  • 7
  • 60
  • 120