-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Expand file tree
/
Copy pathcount-fancy-numbers-in-a-range.cpp
More file actions
115 lines (107 loc) · 4.14 KB
/
count-fancy-numbers-in-a-range.cpp
File metadata and controls
115 lines (107 loc) · 4.14 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
// Time: O(dlogd + g + d^2 + g * d) = O(g * d + d^2), d = logr, g = len(good)
// Space: O(g + d)
// bfs, dp, principle of inclusion and exclusion
class Solution {
public:
long long countFancy(long long l, long long r) {
const auto& count = [&](int64_t x) {
const auto& total = [](int64_t n) { // Time: O(logn)
int result = 0;
for (; n; n /= 10) {
result += n % 10;
}
return result;
};
const auto& length = [](int64_t n) { // Time: O(logn)
int result = 0;
for (; n; n /= 10) {
++result;
}
return result;
};
const auto& check = [](int n) { // Time: O(logn)
bool asc = true, desc = true;
for (; n >= 10; n /= 10) {
if (!((n / 10) % 10 < n % 10)) {
asc = false;
}
if (!((n / 10) % 10 > n % 10)) {
desc = false;
}
}
return asc || desc;
};
const auto& bfs = [](int64_t x) { // Time: O(g), g = len(result)
vector<int64_t> result;
for (int i = 1; i <= min(static_cast<int64_t>(9), x); ++i) {
result.emplace_back(i);
}
for (const auto& diff : {1, -1}) {
vector<int64_t> q;
for (int i = 1; i <= min(static_cast<int64_t>(9), x); ++i) {
q.emplace_back(i);
}
while (!empty(q)) {
vector<int64_t> new_q;
for (const auto& u : q) {
const auto& curr = u % 10;
for (int d = curr + diff; 0 <= d && d <= 9; d += diff) {
const auto& v = u * 10 + d;
if (v <= x) {
new_q.emplace_back(v);
result.emplace_back(v);
}
}
}
q = move(new_q);
}
}
return result;
};
vector<bool> lookup(length(x) * 9 + 1);
const auto& dp = [&](int64_t x) { // Time: O(d^2), d = logr
const auto& l = length(x);
const auto& mx = l * 9;
vector<vector<int64_t>> dp(2, vector<int64_t>(mx + 1)); // dp[tight][sum]
dp[1][0] = 1;
int64_t base = pow(10LL, l - 1);
for (int i = 0; i < l; ++i) {
vector<vector<int64_t>> new_dp(2, vector<int64_t>(mx + 1));
const auto& v = (x / base) % 10;
base /= 10;
for (int t = 0; t < 2; ++t) {
for (int s = 0; s <= mx; ++s) {
if (dp[t][s] == 0) {
continue;
}
const auto& bound = (t == 1) ? v : 9;
for (int d = 0; d <= bound; ++d) {
new_dp[t == 1 && d == v][s + d] += dp[t][s];
}
}
}
dp = move(new_dp);
};
int64_t result = 0;
for (int i = 0; i <= mx; ++i) {
if (lookup[i]) {
result += dp[0][i] + dp[1][i];
}
}
return result;
};
for (int i = 0; i < size(lookup); ++i) {
lookup[i] = check(i);
}
const auto& good = bfs(x);
int64_t cnt = 0;
for (const auto& x : good) {
if (lookup[total(x)]) {
++cnt;
}
}
return size(good) + dp(x) - cnt;
};
return count(r) - count(l - 1);
}
};