1+ /* *
2+ * Author: Ramez
3+ * Description: Function to solve combinatorics problems.
4+ * Time: O(n) for init and O(1) for query
5+ */
6+
7+ namespace combinatorics {
8+ vector<int > fact, inv, invFact;
9+
10+ int pwmod (int a, int b) {
11+ a %= MOD ;
12+ int result = 1 ;
13+ while (b > 0 ) {
14+ if (b & 1 ) result = (result * a) % MOD ;
15+ a = (a * a) % MOD ;
16+ b /= 2 ;
17+ }
18+ return result;
19+ }
20+
21+ int inverse (int x) { return pwmod (x, MOD - 2 ); }
22+ int multiply (int a, int b) { return ((a % MOD ) * (b % MOD )) % MOD ; }
23+ int divide (int a, int b) { return multiply (a, inverse (b)); }
24+
25+ void init (int n) {
26+ fact.resize (n + 1 ); inv.resize (n + 1 ); invFact.resize (n + 1 );
27+ fact[0 ] = fact[1 ] = inv[0 ] = inv[1 ] = invFact[0 ] = invFact[1 ] = 1 ;
28+ for (int i = 2 ; i <= n; ++i){
29+ fact[i] = fact[i - 1 ] * i % MOD ;
30+ inv[i] = MOD - ((MOD / i) * inv[MOD % i]) % MOD ;
31+ invFact[i] = invFact[i - 1 ] * inv[i] % MOD ;
32+ }
33+ }
34+
35+ int nPr (int n, int r) {
36+ if (n < 0 || r < 0 || r > n) return 0 ;
37+ return fact[n] * invFact[n - r] % MOD ;
38+ }
39+
40+ int nCr (int n, int r) {
41+ if (n < 0 || r < 0 || r > n) return 0 ;
42+ return fact[n] * invFact[r] % MOD * invFact[n - r] % MOD ;
43+ }
44+
45+ int nPrLinear (int n, int r){
46+ int answer = 1 ;
47+ for (int i = n - r + 1 ; i <= n; i++){
48+ answer = multiply (answer, i);
49+ }
50+ return answer;
51+ }
52+
53+ int nCrLinear (int n, int r){
54+ int answer = 1 ;
55+ for (int i = r + 1 ; i <= n; i++){
56+ answer = multiply (answer, i);
57+ answer = divide (answer, i - r);
58+ }
59+ return answer;
60+ }
61+ };
62+ using namespace combinatorics ;
0 commit comments