|
| 1 | +--- |
| 2 | +sidebar_position: 2 |
| 3 | +title: Combinatorics |
| 4 | +sidebar_label: Combinatorics |
| 5 | +--- |
| 6 | + |
| 7 | +This document provides an overview of a set of utilities for combinatorics and permutations implemented in C++. The code is designed with modularity and efficiency in mind, suitable for competitive programming scenarios where performance and correctness are paramount. |
| 8 | + |
| 9 | +### 1. Constants and Macros |
| 10 | +- **`md`**: A large prime number ($10^9 + 7$), commonly used as the modulus for competitive programming to avoid overflow and ensure results fit within standard data types. |
| 11 | +- **`ceil(a, b)`**: A macro to calculate the ceiling of the division of two integers, implemented as $\frac{a + b - 1}{b}$. |
| 12 | + |
| 13 | +### 2. Utility Functions |
| 14 | +#### `fastpow` |
| 15 | +```cpp |
| 16 | +const int64_t md = 1e9 + 7; |
| 17 | + |
| 18 | +int64_t fastpow(int64_t a, int64_t b) { |
| 19 | + if (b == 0) |
| 20 | + return 1; |
| 21 | + int64_t half = fastpow(a, b / 2); |
| 22 | + int64_t result = half * half % md; |
| 23 | + if (b & 1) |
| 24 | + result = result * a % md; |
| 25 | + return result; |
| 26 | +} |
| 27 | +``` |
| 28 | +Efficiently computes $a^b \mod \text{md}$ using recursive exponentiation by squaring. This function operates in $O(\log b)$ time, making it suitable for handling large exponents. |
| 29 | +
|
| 30 | +### 3. Precomputations |
| 31 | +#### Factorial Table Construction |
| 32 | +```cpp |
| 33 | +const int MXN = 2e5 + 10; |
| 34 | +int64_t fact[MXN]; |
| 35 | +
|
| 36 | +void buildFactorial() { |
| 37 | + fact[0] = 1; |
| 38 | + for (int i = 1; i < MXN; ++i) { |
| 39 | + fact[i] = fact[i - 1] * i % md; |
| 40 | + } |
| 41 | +} |
| 42 | +``` |
| 43 | +Precomputes factorial values up to a maximum limit (`MXN`) modulo `md`. This precomputation allows for constant-time access to factorial values, which are used extensively in combinatorics calculations. |
| 44 | + |
| 45 | +### 4. Combinatorics |
| 46 | + |
| 47 | +#### Binomial Coefficients (`nCk`) |
| 48 | +```cpp |
| 49 | +auto nCk = [&](int n, int k) -> int64_t { |
| 50 | + return fact[n] * inverse(fact[k] * fact[n - k] % md) % md; |
| 51 | +}; |
| 52 | +``` |
| 53 | +Calculates the binomial coefficient $\binom{n}{k} \mod \text{md}$, representing the number of ways to choose $k$ elements from $n$ elements without repetition. Utilizes modular arithmetic and the precomputed factorials for efficiency. |
| 54 | + |
| 55 | +#### Combinations with Repetition |
| 56 | + |
| 57 | +```cpp |
| 58 | +auto combinationsWithRepetition = [&](int n, int k) -> int64_t { |
| 59 | + return nCk(n + k - 1, k); |
| 60 | +}; |
| 61 | +``` |
| 62 | +Computes combinations with repetition using the formula $\binom{n+k-1}{k}$. This is useful in problems involving the selection of $k$ items from $n$ types with replacement. |
| 63 | + |
| 64 | +### 5. Permutations |
| 65 | +#### Permutations without Repetition |
| 66 | +```cpp |
| 67 | +auto permutations = [&](int n, int k) -> int64_t { |
| 68 | + if (k > n) return 0; |
| 69 | + return fact[n] * inverse(fact[n - k]) % md; |
| 70 | +}; |
| 71 | +``` |
| 72 | +Calculates the number of ways to arrange $k$ items selected from $n$ items without repetition. Returns $0$ if $k > n$. |
| 73 | + |
| 74 | +#### Permutations with Repetition |
| 75 | +```cpp |
| 76 | +auto permutationsWithRepetitions = [&](int n, const vector<int>& m) -> int64_t { |
| 77 | + int64_t product = 1; |
| 78 | + for (int mi : m) { |
| 79 | + assert(0 <= mi); |
| 80 | + product = product * fact[mi] % md; |
| 81 | + } |
| 82 | + return fact[n] * inverse(product) % md; |
| 83 | +}; |
| 84 | +``` |
| 85 | +Determines the number of distinct permutations of $n$ items where some items are repeated. The vector `m` specifies the frequencies of each distinct item. |
| 86 | + |
| 87 | +### 6. Usage Instructions |
| 88 | +1. **Precompute Factorials**: Call `buildFactorial()` at the start of the program to initialize the factorial values. |
| 89 | +2. **Binomial Coefficients**: |
| 90 | +```cpp |
| 91 | +int64_t options = nCk(N, K); |
| 92 | +``` |
| 93 | +Use this for problems involving combinations. |
| 94 | +3. **Combinations with Repetition**: |
| 95 | +```cpp |
| 96 | +int64_t result = combinationsWithRepetition(n, k); |
| 97 | +``` |
| 98 | +Useful for problems where repetition is allowed. |
| 99 | +4. **Permutations**: |
| 100 | +- Without repetition: |
| 101 | +```cpp |
| 102 | +int64_t perm = permutations(n, k); |
| 103 | +``` |
| 104 | +- With repetition: |
| 105 | +```cpp |
| 106 | +vector<int> frequencies = {freq1, freq2, ...}; |
| 107 | +int64_t perm = permutationsWithRepetitions(n, frequencies); |
| 108 | +``` |
| 109 | +
|
| 110 | +### Summary |
| 111 | +This set of utilities provides a robust framework for handling common combinatorics and permutations problems in competitive programming. The modular and efficient design ensures quick computations, leveraging precomputed factorials and modular arithmetic to handle large inputs effectively. |
| 112 | +
|
| 113 | +
|
| 114 | +### References |
| 115 | +- [Source Code Implementation](https://gist.github.com/LuchoBazz/434d918498e61007bba9767bf6469a90) |
| 116 | +
|
0 commit comments