#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; } |
English