public static Modular Combination(int n, int r, int mod = _defaultMod) { if (!FactorialInverseCache.ContainsKey(mod)) { InitializeCombinationTable(maxFactorial, mod); } CheckNR(n, r); r = Math.Min(r, n - r); return(n == r ? new Modular(1, mod) : new Modular(FactorialCache[mod][n], mod) * new Modular(FactorialInverseCache[mod][r], mod) * new Modular(FactorialInverseCache[mod][n - r], mod)); }
private static void InitializeCombinationTable(int max, int mod) { Factorial(max); FactorialInverseCache.Add(mod, new int[max + 1]); long fInv = (new Modular(1, mod) / Factorial(max, mod)).Value; FactorialInverseCache[mod][max] = (int)fInv; for (int i = max - 1; i >= 0; i--) { fInv = (fInv * (i + 1)) % mod; FactorialInverseCache[mod][i] = (int)fInv; } }