#include<iostream>
#include<vector>
#include<cstring>
using namespace std;
#define ull unsigned long long
#define MAX_DIGITS 20
#define LCM 2520
// todo: improve 5?
#define MASK_LEN 256
int add_digit(int s, int dig) {
if (dig < 2) {
return s;
}
return s | (1 << (dig - 2));
}
bool good(int s, int r) {
for (int i = 2; i < 10; i++) {
if ((s & (1 << (i - 2))) != 0) {
// cout << i << " in " << s << endl;
if (r % i != 0) {
return false;
}
else {
// cout << r << ' ' << i << endl;
}
}
else {
// cout << i << " not in " << s << endl;
}
}
return true;
}
ull cup[MAX_DIGITS][MASK_LEN][LCM];
ull cdn[MAX_DIGITS][MASK_LEN][LCM];
ull upto(ull n) {
if (n < 10) {
return n;
}
for (int i = 0; i < MAX_DIGITS; i++) {
for (int j = 0; j < MASK_LEN; j++) {
for (int k = 0; k < LCM; k++) {
cup[i][j][k] = cdn[i][j][k] = 0;
}
}
}
ull up = 10, down = n % up;
for (int i = 1; i < 10; i++) {
cup[0][add_digit(0, i)][i] = 1;
if (i <= down) {
cdn[0][add_digit(0, i)][i] = 1;
}
}
// sdn[0] = 1;
int expo = 0;
int first_of_down;
while (up <= n) {
expo++;
up *= 10;
down = n % up;
first_of_down = (10 * down) / up;
// cout << up << ' ' << down << ' ' << first_of_down << endl;
for (int s = 0; s < MASK_LEN; s++) {
for (int r = 0; r < LCM; r++) {
// if (good(s, r)) {
// sdn[expo] += cup[expo - 1][s][r];
// }
for (int digit = 1; digit < 10; digit++) {
cup[expo][add_digit(s, digit)][(r + digit * (up / 10)) % LCM] += cup[expo - 1][s][r];
if (digit < first_of_down) {
cdn[expo][add_digit(s, digit)][(r + digit * (up / 10)) % LCM] += cup[expo - 1][s][r];
}
else if (digit == first_of_down) {
cdn[expo][add_digit(s, digit)][(r + digit * (up / 10)) % LCM] += cdn[expo - 1][s][r];
}
}
}
}
}
ull res = 0;
for (int s = 0; s < MASK_LEN; s++) {
for (int r = 0; r < LCM; r++) {
if (good(s, r)) {
for (int e = 0; e < expo; e++) {
res += cup[e][s][r];
}
res += cdn[expo][s][r];
// cout << "good: " << s << ' ' << r << ' ';
}
}
}
return res;
}
int main() {
ios::sync_with_stdio(false);
ull p, q;
cin >> p >> q;
ull resq = upto(q);
ull resp = upto(p - 1);
cout << resq - resp << endl;
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 | #include<iostream> #include<vector> #include<cstring> using namespace std; #define ull unsigned long long #define MAX_DIGITS 20 #define LCM 2520 // todo: improve 5? #define MASK_LEN 256 int add_digit(int s, int dig) { if (dig < 2) { return s; } return s | (1 << (dig - 2)); } bool good(int s, int r) { for (int i = 2; i < 10; i++) { if ((s & (1 << (i - 2))) != 0) { // cout << i << " in " << s << endl; if (r % i != 0) { return false; } else { // cout << r << ' ' << i << endl; } } else { // cout << i << " not in " << s << endl; } } return true; } ull cup[MAX_DIGITS][MASK_LEN][LCM]; ull cdn[MAX_DIGITS][MASK_LEN][LCM]; ull upto(ull n) { if (n < 10) { return n; } for (int i = 0; i < MAX_DIGITS; i++) { for (int j = 0; j < MASK_LEN; j++) { for (int k = 0; k < LCM; k++) { cup[i][j][k] = cdn[i][j][k] = 0; } } } ull up = 10, down = n % up; for (int i = 1; i < 10; i++) { cup[0][add_digit(0, i)][i] = 1; if (i <= down) { cdn[0][add_digit(0, i)][i] = 1; } } // sdn[0] = 1; int expo = 0; int first_of_down; while (up <= n) { expo++; up *= 10; down = n % up; first_of_down = (10 * down) / up; // cout << up << ' ' << down << ' ' << first_of_down << endl; for (int s = 0; s < MASK_LEN; s++) { for (int r = 0; r < LCM; r++) { // if (good(s, r)) { // sdn[expo] += cup[expo - 1][s][r]; // } for (int digit = 1; digit < 10; digit++) { cup[expo][add_digit(s, digit)][(r + digit * (up / 10)) % LCM] += cup[expo - 1][s][r]; if (digit < first_of_down) { cdn[expo][add_digit(s, digit)][(r + digit * (up / 10)) % LCM] += cup[expo - 1][s][r]; } else if (digit == first_of_down) { cdn[expo][add_digit(s, digit)][(r + digit * (up / 10)) % LCM] += cdn[expo - 1][s][r]; } } } } } ull res = 0; for (int s = 0; s < MASK_LEN; s++) { for (int r = 0; r < LCM; r++) { if (good(s, r)) { for (int e = 0; e < expo; e++) { res += cup[e][s][r]; } res += cdn[expo][s][r]; // cout << "good: " << s << ' ' << r << ' '; } } } return res; } int main() { ios::sync_with_stdio(false); ull p, q; cin >> p >> q; ull resq = upto(q); ull resp = upto(p - 1); cout << resq - resp << endl; return 0; } |
English