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