Розбір
The answer to the problem will be the value of . Since we need to find the binomial coefficient by modulo, we’ll try to avoid division during calculations. To achieve this, use the relation: .
The problem can also be solved using the formula:
by replacing division with multiplication by the inverse number modulo . Note that the number is a prime. That is, .
According to Fermat’s theorem, or , hence the inverse of modulo will be . Thus,
Algorithm realization
Declare the constants and array , where .
#define MAX 510 #define MOD 9929 int cnk[MAX][MAX];
The c function computes the value of the binomial coefficient .
int c(int n, int k) { if (cnk[n][k] > 0) return cnk[n][k]; if (n - k < k) return c(n,n-k); if (!k) return cnk[n][k] = 1; return cnk[n][k] = (c(n-1,k) + c(n-1,k-1)) % MOD; }
The main part of the program. Initialize the array with zeros. Read the input data.
memset(cnk,0,sizeof(cnk)); scanf("%d %d",&n,&k);
Compute and print the answer.
printf("%d\n",c(n,k));
Algorithm realization – loops
Declare the constants and array , where .
#define MAX 502 #define MOD 9929 int cnk[MAX][MAX];
The FillCnk function fills the array with binomial coefficients.
void FillCnk(void) { int n, k; memset(cnk,0,sizeof(cnk));
Initialize .
for(n = 0; n < MAX; n++) cnk[n][0] = 1;
Perform the computation using the formula modulo .
for(n = 1; n < MAX; n++) for(k = 1; k <= MAX; k++) cnk[n][k] = (cnk[n-1][k] + cnk[n-1][k-1]) % MOD; }
The main part of the program. Fill the array of binomial coefficients.
FillCnk();
Read the input data. Compute and print the answer.
scanf("%d %d",&n,&k); printf("%d\n",cnk[n][k]);
Algorithm realization – inverse modulo
The pow function computes .
int pow(int x, int n, int p) { if (n == 0) return 1; if (n % 2 == 0) return pow((x * x) % p, n / 2, p); return (x * pow(x, n - 1, p)) % p; }
The inverse function computes the number that is the inverse of modulo : (where is prime).
int inverse(int x, int p) { return pow(x, p - 2, p); }
The Cnk function computes the value of the binomial coefficient modulo . To achieve this, rewrite an expression
in the form
int Cnk(int n, int k, int p) { int res = 1; if (k > n - k) k = n - k; for (int i = 1; i <= k; i++) res = ((res * (n - i + 1)) % p * inverse(i, p)) % p; return res; }
The main part of the program. Read the input data.
scanf("%d %d", &n, &k);
Compute and print the answer.
res = Cnk(n, k, 9929); printf("%d\n", res);
Java realization
import java.util.*; public class Main { static int dp[][]; static int MOD = 9929; static int Cnk(int n, int k) { if (n == k) return 1; if (k == 0) return 1; if (dp[n][k] != -1) return dp[n][k]; return dp[n][k] = (Cnk(n - 1, k - 1) + Cnk(n - 1, k)) % MOD; } public static void main(String[] args) { Scanner con = new Scanner(System.in); int n = con.nextInt(); int k = con.nextInt(); dp = new int[n+1][k+1]; for(int i = 0; i <= n; i++) Arrays.fill(dp[i],-1); int res = Cnk(n,k); System.out.println(res); con.close(); } }
Java realization – loops, long arithmetic
import java.util.*; import java.math.*; public class Main { static BigInteger Cnk(int n, int k) { BigInteger res = BigInteger.ONE; BigInteger MOD = BigInteger.valueOf(9929); BigInteger p = BigInteger.valueOf(n); BigInteger q = BigInteger.valueOf(1); for (int i = 0; i < k; i++) { res = res.multiply(p).multiply(q.modInverse(MOD)).mod(MOD); p = p.subtract(BigInteger.ONE); q = q.add(BigInteger.ONE); } return res; } public static void main(String[] args) { Scanner con = new Scanner(System.in); int n = con.nextInt(); int k = con.nextInt(); BigInteger res = Cnk(n,k); System.out.println(res); con.close(); } }
Python realization
The Cnk function computes the value of the binomial coefficient and memoizes its value in the cell .
def Cnk(n, k, dp): if n == k: return 1 if k == 0: return 1 if dp[n][k] != -1: return dp[n][k] dp[n][k] = (Cnk(n - 1, k - 1, dp) + Cnk(n - 1, k, dp)) % 9929 return dp[n][k]
The main part of the program. Read the input data.
n, k = map(int, input().split())
Initialize a two-dimensional list for memoizing the values:
dp = [[-1] * 501 for _ in range(501)]
Compute and print the answer.
print(Cnk(n, k, dp))