Skip to content

Commit 81e945a

Browse files
authored
Create count-the-number-of-good-subsequences.cpp
1 parent f640ada commit 81e945a

File tree

1 file changed

+70
-0
lines changed

1 file changed

+70
-0
lines changed
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
// Time: O(26 * n)
2+
// Space: O(n)
3+
4+
// combinatorics
5+
class Solution {
6+
public:
7+
int countGoodSubsequences(string s) {
8+
vector<int> cnt(26);
9+
for (const auto& c : s) {
10+
++cnt[c - 'a'];
11+
}
12+
uint32_t result = 0;
13+
for (int k = 1; k <= size(s); ++k) {
14+
uint32_t curr = 1;
15+
for (int i = 0; i < size(cnt); ++i) {
16+
curr = mulmod(curr, addmod(1, nCr(cnt[i], k)));
17+
}
18+
result = addmod(result, submod(curr, 1));
19+
}
20+
return result;
21+
}
22+
23+
private:
24+
int nCr(int n, int k) {
25+
if (k < 0 || k > n) {
26+
return 0;
27+
}
28+
while (size(inv_) <= n) { // lazy initialization
29+
fact_.emplace_back(mulmod(fact_.back(), size(inv_)));
30+
inv_.emplace_back(mulmod(inv_[MOD % size(inv_)], MOD - MOD / size(inv_))); // https://cp-algorithms.com/algebra/module-inverse.html
31+
inv_fact_.emplace_back(mulmod(inv_fact_.back(), inv_.back()));
32+
}
33+
return mulmod(mulmod(fact_[n], inv_fact_[n - k]), inv_fact_[k]);
34+
}
35+
36+
uint32_t addmod(uint32_t a, uint32_t b) { // avoid overflow
37+
a %= MOD, b %= MOD;
38+
if (MOD - a <= b) {
39+
b -= MOD; // relied on unsigned integer overflow in order to give the expected results
40+
}
41+
return a + b;
42+
}
43+
44+
uint32_t submod(uint32_t a, uint32_t b) {
45+
a %= MOD, b %= MOD;
46+
return addmod(a, MOD - b);
47+
}
48+
49+
// reference: https://stackoverflow.com/questions/12168348/ways-to-do-modulo-multiplication-with-primitive-types
50+
uint32_t mulmod(uint32_t a, uint32_t b) { // avoid overflow
51+
a %= MOD, b %= MOD;
52+
uint32_t result = 0;
53+
if (a < b) {
54+
swap(a, b);
55+
}
56+
while (b > 0) {
57+
if (b % 2 == 1) {
58+
result = addmod(result, a);
59+
}
60+
a = addmod(a, a);
61+
b /= 2;
62+
}
63+
return result;
64+
}
65+
66+
static const uint32_t MOD = 1e9 + 7;
67+
vector<int> fact_ = {1, 1};
68+
vector<int> inv_ = {1, 1};
69+
vector<int> inv_fact_ = {1, 1};
70+
};

0 commit comments

Comments
 (0)