Combination number C (n, m) the number of m methods from n items
1. When n and m are relatively small, you can use the number corresponding to the Yang Hui triangle for direct calculation.
Int c [N] [N]; memset (c, 0, sizeof (c); int I, j; for (I = 0; I <= N; I ++) {c [I] [0] = c [I] [I] = 1; for (j = 1; j <I; j ++) c [I] [j] = c [i-1] [j-1] + c [i-1] [j];}O (N ^ 2), it is about 1000. The modulo can be directly added.
2. When n and m are relatively small, mod is relatively large, and the number is a prime number, it can be computed through pre-processing inverse element.
Ll inverse [N]; ll power (ll a, ll B) // about the reverse element. In fact, if mod is a prime number, the reverse element of B is actually B ^ (mod-2) {ll ans = 1; while (B) {if (B & 1) ans = (ans * a) % mod; a = (a * a) % mod; b> = 1;} return ans;} ll exgcd (ll a, ll B, ll & x, ll & y) {if (B = 0) {x = 1; y = 0; return a;} ll t, r = exgcd (B, a % B, x, y); t = x; x = y; y = t-a/B * y; return r;} ll get_inverse (ll a) // exgcd evaluate the reverse element {ll x, y; exgcd (a, mod, x, y); return (x % mod + mod) % mod;} ll fc (ll n, ll m) {/* ll t1, t2; // if the data is small, multiply it directly and obtain the last reverse element fast t1 = t2 = 1; for (ll I = n; I> m; I --) {t1 = (t1 * I) % mod; t2 = (t2 * (I-m) % mod;} return t1 * get_inverse (t2) % mod; */ll ans = 1; // if the data is large, the reverse element used for preprocessing is multiplied by the reverse element for (ll I = n; I> m; I --) {ans = (ans * I) % mod; ans = (ans * inverse [I-m]) % mod;} return ans;} int main () {for (int I = 1; I <= N; I ++) inverse [I] = power (I, mod-2 ); // pre-processing inverse element for (int I = 1; I <= N; I ++) inverse [I] = get_inverse (I); // pre-processing inverse element}
O (N) or so
3. When n and m are relatively large, mod is a prime number and relatively small (about 10 ^ 5), it is calculated through the Lucas theorem.
Lucas theorem: solving C (n, m, mod) = Lucas (n, m, mod)
Lucas (n, m, mod) = C (n % mod, m % mod, mod) * Lucas (n/mod, m/mod, mod)
Return 1 when m = 0
Note that n <m appears in C (n % mod, m % mod, mod) and return 0 is required.
Ll power (ll a, ll B, ll mod) {ll ans = 1; while (B) {if (B & 1) ans = (ans * a) % mod; a = (a * a) % mod; B >>= 1;} return ans % mod;} ll fc (ll n, ll m, ll mod) // You can also preprocess all mod factorial {if (m> n) return 0; // add ll t1, t2; t1 = t2 = 1; for (ll I = n; I> m; I --) {t1 = (t1 * I) % mod; t2 = (t2 * (I-m) % mod ;} return (t1 * power (t2, mod-2) % mod;} ll lucas (ll n, ll m, ll mod) {if (m = 0) return 1; ll ans; ans = fc (n % mod, m % mod); return (ans * lucas (n/mod, m/mod, mod) % mod ;}About O (mod)
Simple record of the combination number method