#include<cstdio> const int NWW = 2520; int digits[20]; int len; long long d[20][2][(1 << 9) + 10][NWW]; void reset() { for (int i = 0; i < 20; ++i) for (int j = 0; j < 2; ++j) for (int k = 0; k < (1 << 9) + 10; ++k) for (int l = 0; l < NWW; ++l) d[i][j][k][l] = -1LL; } long long solve(int pos, int constr, int used, int remainder) { int constr_, used_, remainder_; if (d[pos][constr][used][remainder] == -1) { if (pos == 0) { if (used == 0) { d[pos][constr][used][remainder] = 0LL; return 0LL; } for (int i = 2; i < 10; ++i) { if (used & (1 << (i - 1))) { if (remainder % i) { d[pos][constr][used][remainder] = 0LL; return 0LL; } } } d[pos][constr][used][remainder] = 1LL; } else { long long res = 0LL; int min_digit = used ? 1 : 0; int max_digit = constr ? digits[pos - 1] : 9; for (int i = min_digit; i <= max_digit; ++i) { remainder_ = (remainder * 10 + i) % NWW; constr_ = constr ? (i == digits[pos - 1]) : 0; used_ = used; if (i) used_ = used | (1 << (i - 1)); res += solve(pos - 1, constr_, used_, remainder_); } d[pos][constr][used][remainder] = res; } } return d[pos][constr][used][remainder]; } long long potyczkow(long long n) { if (n == 0) return 0LL; len = 0; while (n) { digits[len++] = n % 10; n /= 10; } reset(); return solve(len, 1, 0, 0); } int main() { long long L, R; scanf("%lld %lld", &L, &R); printf("%lld\n", potyczkow(R) - potyczkow(L - 1)); 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 | #include<cstdio> const int NWW = 2520; int digits[20]; int len; long long d[20][2][(1 << 9) + 10][NWW]; void reset() { for (int i = 0; i < 20; ++i) for (int j = 0; j < 2; ++j) for (int k = 0; k < (1 << 9) + 10; ++k) for (int l = 0; l < NWW; ++l) d[i][j][k][l] = -1LL; } long long solve(int pos, int constr, int used, int remainder) { int constr_, used_, remainder_; if (d[pos][constr][used][remainder] == -1) { if (pos == 0) { if (used == 0) { d[pos][constr][used][remainder] = 0LL; return 0LL; } for (int i = 2; i < 10; ++i) { if (used & (1 << (i - 1))) { if (remainder % i) { d[pos][constr][used][remainder] = 0LL; return 0LL; } } } d[pos][constr][used][remainder] = 1LL; } else { long long res = 0LL; int min_digit = used ? 1 : 0; int max_digit = constr ? digits[pos - 1] : 9; for (int i = min_digit; i <= max_digit; ++i) { remainder_ = (remainder * 10 + i) % NWW; constr_ = constr ? (i == digits[pos - 1]) : 0; used_ = used; if (i) used_ = used | (1 << (i - 1)); res += solve(pos - 1, constr_, used_, remainder_); } d[pos][constr][used][remainder] = res; } } return d[pos][constr][used][remainder]; } long long potyczkow(long long n) { if (n == 0) return 0LL; len = 0; while (n) { digits[len++] = n % 10; n /= 10; } reset(); return solve(len, 1, 0, 0); } int main() { long long L, R; scanf("%lld %lld", &L, &R); printf("%lld\n", potyczkow(R) - potyczkow(L - 1)); return 0; } |