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
| class Solution { public: const int MOD = 1e9 + 7; int calc(string s, int b) { int n = s.size(); vector<vector<int>> memo(n + 1, vector<int>(10, -1)); auto dfs = [&](auto&& dfs, int i, bool is_limit, bool is_num, int pre) -> int { if(i == n) { return is_num; } int res = 0; if(!is_num) { res = (res + dfs(dfs, i + 1, false, false, 0)) % MOD; } if(!is_limit && is_num && memo[i][pre] != -1) return memo[i][pre]; int up = is_limit ? s[i] - '0' : b - 1; for(int d = 1 - is_num; d <= up; d++) { if(!is_num) { res = (res + dfs(dfs, i + 1, is_limit && d == up, true, d)) % MOD; }else{ if(d >= pre) { res = (res + dfs(dfs, i + 1, is_limit && d == up, true, d)) % MOD; } } } if(!is_limit && is_num) memo[i][pre] = res; return res; }; return dfs(dfs, 0, true, false, 0); } string func(string s, int b) { string result; while (!s.empty()) { int remainder = 0; string quotient; for (char c : s) { int current = remainder * 10 + (c - '0'); if (current < b && quotient.empty()) { remainder = current; } else { quotient.push_back(current / b + '0'); remainder = current % b; } } result.push_back(remainder + '0'); s = quotient; } reverse(result.begin(), result.end()); return result; } int countNumbers(string low, string high, int b) { for(int i = low.size(); i--; i >= 0) { if(low[i] > '0') { low[i]--; break; }else{ low[i] = '9'; } } high = func(high, b); low = func(low, b);
return (calc(high, b) - calc(low, b) + MOD) % MOD; } };
|