Problem: the number of combinations is C (n, m), that is, the number of m solutions is extracted from n identical items. Because the results may be very large, the result can be modeled as 10007.
Solution 1:
Brute force solution, C (n, m) = n * (n-1) *... * (n-m + 1)/m !, N <= 15
[Cpp]
Int Combination (int n, int m)
{
Const int M = 10007;
Int ans = 1;
For (int I = n; I >=( n-m + 1); -- I)
Ans * = I;
While (m)
Ans/= m --;
Return ans % M;
}
Int Combination (int n, int m)
{
Const int M = 10007;
Int ans = 1;
For (int I = n; I >=( n-m + 1); -- I)
Ans * = I;
While (m)
Ans/= m --;
Return ans % M;
}
Solution 2:
Create a table, C (n, m) = C (N-1 m-1) + C (n-1, m), n <= 10,000
[Cpp]
Const int M = 10007;
Const int MAXN = 1000;
Int C [MAXN + 1] [MAXN + 1];
Void Initial ()
{
Int I, j;
For (I = 0; I <= MAXN; ++ I)
{
C [0] [I] = 0;
C [I] [0] = 1;
}
For (I = 1; I <= MAXN; ++ I)
{
For (j = 1; j <= MAXN; ++ j)
C [I] [j] = (C [I-1] [j] + C [I-1] [J-1]) % M;
}
}
Int Combination (int n, int m)
{
Return C [n] [m];
}
Const int M = 10007;
Const int MAXN = 1000;
Int C [MAXN + 1] [MAXN + 1];
Void Initial ()
{
Int I, j;
For (I = 0; I <= MAXN; ++ I)
{
C [0] [I] = 0;
C [I] [0] = 1;
}
For (I = 1; I <= MAXN; ++ I)
{
For (j = 1; j <= MAXN; ++ j)
C [I] [j] = (C [I-1] [j] + C [I-1] [J-1]) % M;
}
}
Int Combination (int n, int m)
{
Return C [n] [m];
}
Solution 3:
Prime factor decomposition, C (n, m) = n! /(M! * (N-m )!), C (n, m) = p1a1-b1-c1p2a2-b2-c2... Pkak-bk-ck, n <= 10,000,000
[Cpp]
# Include <cstdio>
Const int maxn = 1000000;
# Include <vector>
Using namespace std;
Bool arr [maxn + 1] = {false };
Vector <int> produce_prim_number ()
{
Vector <int> prim;
Prim. push_back (2 );
Int I, j;
For (I = 3; I * I <= maxn; I + = 2)
{
If (! Arr [I])
{
Prim. push_back (I );
For (j = I * I; j <= maxn; j + = I)
Arr [j] = true;
}
}
While (I <maxn)
{
If (! Arr [I])
Prim. push_back (I );
I + = 2;
}
Return prim;
}
// Calculate n! Exponent of prime factor p in
Int cal (int x, int p)
{
Int ans = 0;
Long rec = p;
While (x> = rec)
{
Ans + = x/rec;
Rec * = p;
}
Return ans;
}
// Calculate the modulo of m to the k power of n.
Int pow (long n, int k, int M)
{
Long ans = 1;
While (k)
{
If (k & 1)
{
Ans = (ans * n) % M;
}
N = (n * n) % M;
K> = 1;
}
Return ans;
}
// Calculate C (n, m)
Int combination (int n, int m)
{
Const int M = 10007;
Vector <int> prim = produce_prim_number ();
Long ans = 1;
Int num;
For (int I = 0; I <prim. size () & prim [I] <= n; ++ I)
{
Num = cal (n, prim [I])-cal (m, prim [I])-cal (n-m, prim [I]);
Ans = (ans * pow (prim [I], num, M) % M;
}
Return ans;
}
Int main ()
{
Int m, n;
While (~ Scanf ("% d", & m, & n), m & n)
{
Printf ("% d \ n", combination (m, n ));
}
Return 0;
}
# Include <cstdio>
Const int maxn = 1000000;
# Include <vector>
Using namespace std;
Bool arr [maxn + 1] = {false };
Vector <int> produce_prim_number ()
{
Vector <int> prim;
Prim. push_back (2 );
Int I, j;
For (I = 3; I * I <= maxn; I + = 2)
{
If (! Arr [I])
{
Prim. push_back (I );
For (j = I * I; j <= maxn; j + = I)
Arr [j] = true;
}
}
While (I <maxn)
{
If (! Arr [I])
Prim. push_back (I );
I + = 2;
}
Return prim;
}
// Calculate n! Exponent of prime factor p in
Int cal (int x, int p)
{
Int ans = 0;
Long rec = p;
While (x> = rec)
{
Ans + = x/rec;
Rec * = p;
}
Return ans;
}
// Calculate the modulo of m to the k power of n.
Int pow (long n, int k, int M)
{
Long ans = 1;
While (k)
{
If (k & 1)
{
Ans = (ans * n) % M;
}
N = (n * n) % M;
K> = 1;
}
Return ans;
}
// Calculate C (n, m)
Int combination (int n, int m)
{
Const int M = 10007;
Vector <int> prim = produce_prim_number ();
Long ans = 1;
Int num;
For (int I = 0; I <prim. size () & prim [I] <= n; ++ I)
{
Num = cal (n, prim [I])-cal (m, prim [I])-cal (n-m, prim [I]);
Ans = (ans * pow (prim [I], num, M) % M;
}
Return ans;
}
Int main ()
{
Int m, n;
While (~ Scanf ("% d", & m, & n), m & n)
{
Printf ("% d \ n", combination (m, n ));
}
Return 0;
}
Solution 4:
The Lucas theorem converts m and n into p-hexadecimal values, including C (n, m) = C (n0, m0) * C (n1, m1 )... (mod p), calculate a non-very large C (n, m) % p, p as a prime number, convert it into a linear homogeneous equation, and use the Extended Euclidean theorem to solve the problem, if n is within the int range, the modification can be within the long range.
[Cpp]
# Include <stdio. h>
Const int M = 10007;
Int ff [M + 5]; // type a table and record n !, Avoid repeated computing
// Calculate the maximum public factor
Int gcd (int a, int B)
{
If (B = 0)
Return;
Else
Return gcd (B, a % B );
}
// Solves linear homogeneous equations and extends Euclidean Theorem
Int x, y;
Void Extended_gcd (int a, int B)
{
If (B = 0)
{
X = 1;
Y = 0;
}
Else
{
Extended_gcd (B, a % B );
Long t = x;
X = y;
Y = t-(a/B) * y;
}
}
// C (n, m) that is not much computed)
Int C (int a, int B)
{
If (B>)
Return 0;
B = (ff [a-B] * ff [B]) % M;
A = ff [a];
Int c = gcd (a, B );
A/= c;
B/= c;
Extended_gcd (B, M );
X = (x + M) % M;
X = (x * a) % M;
Return x;
}
// Lucas Theorem
Int Combination (int n, int m)
{
Int ans = 1;
Int a, B;
While (m | n)
{
A = n % M;
B = m % M;
N/= M;
M/= M;
Ans = (ans * C (a, B) % M;
}
Return ans;
}
Int main (void)
{
Int I, m, n;
Ff [0] = 1;
For (I = 1; I <= M; I ++) // pre-calculate n!
Ff [I] = (ff [I-1] * I) % M;
Scanf ("% d", & n, & m );
Printf ("% d \ n", func (n, m ));
Return 0;
}
# Include <stdio. h>
Const int M = 10007;
Int ff [M + 5]; // type a table and record n !, Avoid repeated computing
// Calculate the maximum public factor
Int gcd (int a, int B)
{
If (B = 0)
Return;
Else
Return gcd (B, a % B );
}
// Solves linear homogeneous equations and extends Euclidean Theorem
Int x, y;
Void Extended_gcd (int a, int B)
{
If (B = 0)
{
X = 1;
Y = 0;
}
Else
{
Extended_gcd (B, a % B );
Long t = x;
X = y;
Y = t-(a/B) * y;
}
}
// C (n, m) that is not much computed)
Int C (int a, int B)
{
If (B>)
Return 0;
B = (ff [a-B] * ff [B]) % M;
A = ff [a];
Int c = gcd (a, B );
A/= c;
B/= c;
Extended_gcd (B, M );
X = (x + M) % M;
X = (x * a) % M;
Return x;
}
// Lucas Theorem
Int Combination (int n, int m)
{
Int ans = 1;
Int a, B;
While (m | n)
{
A = n % M;
B = m % M;
N/= M;
M/= M;
Ans = (ans * C (a, B) % M;
}
Return ans;
}
Int main (void)
{
Int I, m, n;
Ff [0] = 1;
For (I = 1; I <= M; I ++) // pre-calculate n!
Ff [I] = (ff [I-1] * I) % M;
Scanf ("% d", & n, & m );
Printf ("% d \ n", func (n, m ));
Return 0;
}