This kind of question is purely tortured. It's so easy, TLE. I didn't do it for one morning yesterday. Today it's a correct one. I'm tired of typing prime numbers into a table, but it will be faster after the table is played.
Each number can be expressed by m = p1 ^ a1 * p2 ^ a2 *... * pn ^ an, so the number of its factors is
(A1 + 1) * (a2 + 1 )*... * (an + 1) is very simple. Each factor has an index of 0, 1, 2 .... to your own ai + 1 choice.
So: We need C (n, m) = n! /(N-m )! M! ), So we can find N! The factor and its index, then
Ans = f [n]-f [n-m]-f [m] + 1 Where f [I] represents I! And its index.
It takes a little longer to create a table with a prime number. So I try to avoid the number of prime numbers in the table.
Code:
# Include <iostream>
Using namespace std;
Int f [510], p [510], len, a [510] [510];
_ Int64 dp [510] [510];
Void Prime ()
{
Int I, j;
Len = 0;
Memset (f, 0, sizeof (f ));
For (I = 2; I * I <= 500; I ++) {// a prime number with a square less than 500
If (! F [I]) {
P [len ++] = I;
For (j = 2 * I; j x <= 500; j + = I)
F [j] = 1;
}
}
}
Void Solve ()
{
Int I, j, n;
Memset (a, 0, sizeof ());
For (I = 2; I <= 435; I ++ ){
For (j = 0; j <I; j ++)
A [I] [j] = a [I-1] [j];
N = I;
For (j = 0; j <len & n> 1; j ++ ){
While (n % p [j] = 0 ){
A [I] [p [j] ++;
N/= p [j];
}
}
If (n> 1) a [I] [n] + +; // There is a prime number greater than p [len-1] * p [len-1.
}
}
Int main ()
{
Int I, j, sum, n, k;
Prime ();
Solve ();
// Freopen ("prime.txt", "w", stdout );
Memset (dp, 0, sizeof (dp ));
While (scanf ("% d", & n, & k )! = EOF ){
If (dp [n] [k]) {printf ("% I64d \ n", dp [n] [k]); continue ;}
_ Int64 sum = 1;
For (I = 2; I <= n; I ++)
If (! F [I]) // is a prime number or greater than p [len-1] * p [len-1]
Sum * = (a [n] [I]-a [n-k] [I]-a [k] [I] + 1 );
Dp [n] [k] = dp [n] [n-k] = sum;
Printf ("% I64d \ n", sum );
}
Return 0;
}