Idea: In the past, when I was playing a game, I encountered a lot of situations where I had to calculate the number of combinations. I tried to write recursion instead of brute force or timeout, or because I had to take the modulo, then we also need to reverse the yuan, so if it is not slow, it is always a problem, so now we can work out a template and use it quickly.
1. linearly evaluate C (n, m)
Explanation: The number of combinations obtained by the HDU 4927 question can be used to understand some recursive quick methods of the number of combinations, because this question is the time of the number of cards. If we want to calculate C (), we can calculate C () first, then C (), then C (), and then C ). Why am I asking for this?
Because: C (10/1) = 9/2, then C () * is equal to C (), that is, C () = 10*9/(2*1 ); then C (8/3) * is equal to C (), that is, C () = 10*9*8/(3*2*1); then C) * 7/4 is equal to C (10, 4), that is, C (10, 4) = 10*9*8*7/(4*3*2*1 ). At first, I was worried that the numerator might not be divisible when divided by the denominator, but rest assured that it has proved that every combination obtained through recursive calculation is correct, no decimal point.
Therefore, according to this nature or law, you can use the code to linearly find C (n, m:
Ll combine1 (ll n, ll m) // calculates the number of combinations C (n, m) {ll sum = 1; // linear calculation for (ll I = 1, j = N; I <= m; I ++, j --) sum = sum * j/I; return sum ;}
2. recursively evaluate C (n, m)
From C (n, m) = C (N-1 m-1) + C (n-1, m), we can use the code to recursively obtain the value of C (n, m:
Ll combine2 (ll n, ll m) // calculates the number of combinations C (n, m) {If (n = M |! M) return 1; // recursive computation return combine2 (n-1, m) + combine2 (N-1 m-1 );}
Two kinds of comparison: The linear number of combinations is fast, and each request can only go from 1 to M. But recursion does not work. When C (50, 25) is computed, it has timed out and becomes violent, after waiting for a long time, I can't get the answer, so I can use linear code later!
3. Calculate C (n, m) % mod linearly.
Void extend_gcd (ll a, LL B, ll & D, ll & X, ll & Y) {If (! B) d = A, x = 1, y = 0; else {extend_gcd (B, A % B, D, Y, X ); y-= x * (a/B);} ll Mod (ll a, LL B, ll mod) // The calculated reverse yuan is incorrect. Check it tomorrow before {If (! B) return 1; ll ans = Mod (a, B> 1, MoD); ans = ans * ans % MOD; If (B & 1) ans = ans * A % MOD; return ans;} ll inv (ll a, ll mod) // calculate the reverse element of MOD of A {ll D, X, Y; extend_gcd (A, Mod, D, x, y); Return d = 1? (X + mod) % mod:-1; // return Mod (A, mod-2, MoD);} ll combine1 (ll n, ll M, ll mod) // computing combination C (n, m) % mod {ll sum = 1; // linear calculation for (ll I = 1, j = N; I <= m; I ++, j --) sum = sum * j * inv (I, MoD) % MOD; return sum ;}