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