#include <iostream>
using namespace std;
const long long INF = (1LL<<60);
const int MOD = 2520;
int len(long long x) {
int res = 1;
while (x /= 10) res++;
return res;
}
long long pow(int a, int n) {
long long res = 1;
while (n--) res *= a;
return res;
}
bool is_allowed_digit[10], is_allowed_rest[MOD];
long long cache[19][MOD];
long long f(int len, long long max=INF, int rest=0) {
if (len == 0) return is_allowed_rest[rest];
if (max >= pow(10, len) && cache[len][rest] != -1) return cache[len][rest];
long long res = 0;
for (int d=1; d<=9; d++) {
if (!is_allowed_digit[d]) continue;
long long val = d * pow(10, len-1);
if (val >= max) break;
res += f(len-1, max-val, (rest + val) % MOD);
}
if (max >= pow(10, len)) cache[len][rest] = res;
return res;
}
int main() {
long long l, r;
cin >> l >> r;
int ll = len(l), lr = len(r);
long long res = 0;
is_allowed_digit[1] = true;
for (int i=0; i<(1<<8); i++) {
for (int i=0; i<=18; i++)
for (int j=0; j<MOD; j++) cache[i][j] = -1;
for (int j=0; j<8; j++) is_allowed_digit[j+2] = (i&(1<<j));
int allowed_rests = 0;
for (int r=0; r<MOD; r++) {
is_allowed_rest[r] = true;
for (int d=2; d<=9; d++) if ((r%d == 0) != (is_allowed_digit[d])) is_allowed_rest[r] = false;
allowed_rests += is_allowed_rest[r];
}
if (allowed_rests == 0) continue;
res += f(lr, r+1) - f(ll, l);
for (int i=ll; i<lr; i++) res += f(i);
}
cout << res << "\n";
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 | #include <iostream> using namespace std; const long long INF = (1LL<<60); const int MOD = 2520; int len(long long x) { int res = 1; while (x /= 10) res++; return res; } long long pow(int a, int n) { long long res = 1; while (n--) res *= a; return res; } bool is_allowed_digit[10], is_allowed_rest[MOD]; long long cache[19][MOD]; long long f(int len, long long max=INF, int rest=0) { if (len == 0) return is_allowed_rest[rest]; if (max >= pow(10, len) && cache[len][rest] != -1) return cache[len][rest]; long long res = 0; for (int d=1; d<=9; d++) { if (!is_allowed_digit[d]) continue; long long val = d * pow(10, len-1); if (val >= max) break; res += f(len-1, max-val, (rest + val) % MOD); } if (max >= pow(10, len)) cache[len][rest] = res; return res; } int main() { long long l, r; cin >> l >> r; int ll = len(l), lr = len(r); long long res = 0; is_allowed_digit[1] = true; for (int i=0; i<(1<<8); i++) { for (int i=0; i<=18; i++) for (int j=0; j<MOD; j++) cache[i][j] = -1; for (int j=0; j<8; j++) is_allowed_digit[j+2] = (i&(1<<j)); int allowed_rests = 0; for (int r=0; r<MOD; r++) { is_allowed_rest[r] = true; for (int d=2; d<=9; d++) if ((r%d == 0) != (is_allowed_digit[d])) is_allowed_rest[r] = false; allowed_rests += is_allowed_rest[r]; } if (allowed_rests == 0) continue; res += f(lr, r+1) - f(ll, l); for (int i=ll; i<lr; i++) res += f(i); } cout << res << "\n"; return 0; } |
English