Skip to content

Commit 9566cf0

Browse files
authored
Create number-of-ways-to-reach-a-position-after-exactly-k-steps.cpp
1 parent 7324f51 commit 9566cf0

File tree

1 file changed

+51
-0
lines changed

1 file changed

+51
-0
lines changed
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
// Time: O(k)
2+
// Space: O(k)
3+
4+
// combinatorics
5+
class Solution {
6+
public:
7+
int numberOfWays(int startPos, int endPos, int k) {
8+
const int r = k - abs(endPos - startPos);
9+
return r >= 0 && r % 2 == 0 ? nCr(k, r / 2) : 0;
10+
}
11+
12+
private:
13+
int nCr(int n, int k) {
14+
while (size(inv_) <= n) { // lazy initialization
15+
fact_.emplace_back(mulmod(fact_.back(), size(inv_)));
16+
inv_.emplace_back(mulmod(inv_[MOD % size(inv_)], MOD - MOD / size(inv_))); // https://cp-algorithms.com/algebra/module-inverse.html
17+
inv_fact_.emplace_back(mulmod(inv_fact_.back(), inv_.back()));
18+
}
19+
return mulmod(mulmod(fact_[n], inv_fact_[n - k]), inv_fact_[k]);
20+
}
21+
22+
uint32_t addmod(uint32_t a, uint32_t b) { // avoid overflow
23+
a %= MOD, b %= MOD;
24+
if (MOD - a <= b) {
25+
b -= MOD; // relied on unsigned integer overflow in order to give the expected results
26+
}
27+
return a + b;
28+
}
29+
30+
// reference: https://stackoverflow.com/questions/12168348/ways-to-do-modulo-multiplication-with-primitive-types
31+
uint32_t mulmod(uint32_t a, uint32_t b) { // avoid overflow
32+
a %= MOD, b %= MOD;
33+
uint32_t result = 0;
34+
if (a < b) {
35+
swap(a, b);
36+
}
37+
while (b > 0) {
38+
if (b % 2 == 1) {
39+
result = addmod(result, a);
40+
}
41+
a = addmod(a, a);
42+
b /= 2;
43+
}
44+
return result;
45+
}
46+
47+
static const uint32_t MOD = 1e9 + 7;
48+
vector<int> fact_ = {1, 1};
49+
vector<int> inv_ = {1, 1};
50+
vector<int> inv_fact_ = {1, 1};
51+
};

0 commit comments

Comments
 (0)