#include <cstdio> #include <vector> #include <map> using namespace std; int NWD(int a, int b) { if (a < b) { int t = a; a = b; b = t; } while (b > 0) { int t = a; a = b; b = t%b; } return a; } int NWW(int a, int b) { return a * b / NWD(a, b); } int newd[2521][10]; int rest[18][10]; inline void add(int &a, int b) { a += b; if (a >= 2520) a -= 2520; } struct Task { int k; int r; int d; bool operator<(const Task &oth) const { if (k != oth.k) return k > oth.k; if (r != oth.r) return r < oth.r; return d < oth.d; } }; map<Task, long long> todo; bool check(long long n) { long long org = n; while (n > 0) { int d = n % 10; if (d == 0) return false; if (org % d != 0) return false; n /= 10; } return true; } void init(long long n, int val) { if (n <= 0) return; vector<int> v; while (n > 0) { v.push_back(n % 10); n /= 10; } for (int i = 0; i + 1<v.size(); ++i) { Task t = { i, 0, 1 }; todo[t] += val; } int r = 0; int dz = 1; while (!v.empty()) { int dd = v.back(); v.pop_back(); if (dd == 0) return; int pos = v.size(); for (int d = 1; d<dd; ++d) { int rr = r; add(rr, rest[pos][d]); Task t = { pos - 1, rr, newd[dz][d] }; todo[t] += val; } add(r, rest[pos][dd]); dz = newd[dz][dd]; } todo[{ -1, r, dz}] += val; } int main() { { for (int p2 = 1; p2 <= 8; p2 *= 2) for (int p3 = 1; p3 <= 9; p3 *= 3) for (int p5 = 1; p5 <= 5; p5 *= 5) for (int p7 = 1; p7 <= 7; p7 *= 7) { for (int d = 1; d <= 9; ++d) newd[p2*p3*p5*p7][d] = NWW(p2*p3*p5*p7, d); } int mn = 1; for (int pos = 0; pos<18; ++pos) { for (int d = 1; d <= 9; ++d) { rest[pos][d] = mn * d; rest[pos][d] %= 2520; } mn *= 10; mn %= 2520; } } long long a, b; scanf("%lld%lld", &a, &b); init(a - 1, -1); init(b, 1); long long res = 0; while (!todo.empty()) { Task t = todo.begin()->first; long long cur = todo.begin()->second; todo.erase(t); if (cur == 0) continue; if (t.k < 0) { if (t.r % t.d == 0) res += cur; continue; } for (int d = 1; d <= 9; ++d) { Task tt = t; --tt.k; add(tt.r, rest[t.k][d]); tt.d = newd[t.d][d]; todo[tt] += cur; } } printf("%lld\n", res); return 0; }
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 116 117 118 119 120 | #include <cstdio> #include <vector> #include <map> using namespace std; int NWD(int a, int b) { if (a < b) { int t = a; a = b; b = t; } while (b > 0) { int t = a; a = b; b = t%b; } return a; } int NWW(int a, int b) { return a * b / NWD(a, b); } int newd[2521][10]; int rest[18][10]; inline void add(int &a, int b) { a += b; if (a >= 2520) a -= 2520; } struct Task { int k; int r; int d; bool operator<(const Task &oth) const { if (k != oth.k) return k > oth.k; if (r != oth.r) return r < oth.r; return d < oth.d; } }; map<Task, long long> todo; bool check(long long n) { long long org = n; while (n > 0) { int d = n % 10; if (d == 0) return false; if (org % d != 0) return false; n /= 10; } return true; } void init(long long n, int val) { if (n <= 0) return; vector<int> v; while (n > 0) { v.push_back(n % 10); n /= 10; } for (int i = 0; i + 1<v.size(); ++i) { Task t = { i, 0, 1 }; todo[t] += val; } int r = 0; int dz = 1; while (!v.empty()) { int dd = v.back(); v.pop_back(); if (dd == 0) return; int pos = v.size(); for (int d = 1; d<dd; ++d) { int rr = r; add(rr, rest[pos][d]); Task t = { pos - 1, rr, newd[dz][d] }; todo[t] += val; } add(r, rest[pos][dd]); dz = newd[dz][dd]; } todo[{ -1, r, dz}] += val; } int main() { { for (int p2 = 1; p2 <= 8; p2 *= 2) for (int p3 = 1; p3 <= 9; p3 *= 3) for (int p5 = 1; p5 <= 5; p5 *= 5) for (int p7 = 1; p7 <= 7; p7 *= 7) { for (int d = 1; d <= 9; ++d) newd[p2*p3*p5*p7][d] = NWW(p2*p3*p5*p7, d); } int mn = 1; for (int pos = 0; pos<18; ++pos) { for (int d = 1; d <= 9; ++d) { rest[pos][d] = mn * d; rest[pos][d] %= 2520; } mn *= 10; mn %= 2520; } } long long a, b; scanf("%lld%lld", &a, &b); init(a - 1, -1); init(b, 1); long long res = 0; while (!todo.empty()) { Task t = todo.begin()->first; long long cur = todo.begin()->second; todo.erase(t); if (cur == 0) continue; if (t.k < 0) { if (t.r % t.d == 0) res += cur; continue; } for (int d = 1; d <= 9; ++d) { Task tt = t; --tt.k; add(tt.r, rest[t.k][d]); tt.d = newd[t.d][d]; todo[tt] += cur; } } printf("%lld\n", res); return 0; } |