#include <bits/stdc++.h> using namespace std; #define REP(i,n) for(int _n=(n), i=0;i<_n;++i) #define FOR(i,a,b) for(int i=(a),_b=(b);i<=_b;++i) #define FORD(i,a,b) for(int i=(a),_b=(b);i>=_b;--i) #define TRACE(x) cerr << "TRACE(" #x ")" << endl; #define DEBUG(x) cerr << #x << " = " << (x) << endl; typedef long long LL; typedef unsigned long long ULL; const int MAX_LEN = 18; const unsigned PERIOD = 8 * 9 * 5 * 7; LL POW10[MAX_LEN+1]; void calc_pow10() { POW10[0] = 1; FOR(i,1,MAX_LEN) POW10[i] = POW10[i-1] * 10; } LL cache[MAX_LEN+1][PERIOD]; LL below_len(unsigned allowed_digits, LL limit, int len, unsigned rem) { LL *cache_ptr = nullptr; if (limit == POW10[len]) cache_ptr = &cache[len][rem]; if (cache_ptr && *cache_ptr != -1) return *cache_ptr; LL res = 0; if (len == 0) { res = 1; FOR(digit, 1, 9) { res = res && ((allowed_digits >> digit)&1u) == (rem % digit == 0); } } else { FOR(digit, 1, 9) { if ((allowed_digits & (1u << digit)) == 0) continue; LL limit2 = limit - digit * POW10[len-1]; unsigned rem2 = (10u * rem + digit) % PERIOD; if (limit2 > 0) { res += below_len(allowed_digits, min(limit2, POW10[len-1]), len-1, rem2); } } } if (cache_ptr) *cache_ptr = res; return res; } LL between(LL limit1, LL limit2) { LL res = 0; for (unsigned allowed_digits = 0; allowed_digits < (1u << 10); allowed_digits += 2u) { FOR(len, 0, MAX_LEN) REP(p, PERIOD) cache[len][p] = -1; for (int len=1; limit2 > POW10[len-1]; ++len) { res += below_len(allowed_digits, min(limit2, POW10[len]), len, 0); res -= below_len(allowed_digits, min(limit1, POW10[len]), len, 0); } } return res; } int main() { cin.tie(nullptr); ios::sync_with_stdio(false); calc_pow10(); LL a, b; cin >> a >> b; LL res = between(a, b+1); cout << res << "\n"; }
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 | #include <bits/stdc++.h> using namespace std; #define REP(i,n) for(int _n=(n), i=0;i<_n;++i) #define FOR(i,a,b) for(int i=(a),_b=(b);i<=_b;++i) #define FORD(i,a,b) for(int i=(a),_b=(b);i>=_b;--i) #define TRACE(x) cerr << "TRACE(" #x ")" << endl; #define DEBUG(x) cerr << #x << " = " << (x) << endl; typedef long long LL; typedef unsigned long long ULL; const int MAX_LEN = 18; const unsigned PERIOD = 8 * 9 * 5 * 7; LL POW10[MAX_LEN+1]; void calc_pow10() { POW10[0] = 1; FOR(i,1,MAX_LEN) POW10[i] = POW10[i-1] * 10; } LL cache[MAX_LEN+1][PERIOD]; LL below_len(unsigned allowed_digits, LL limit, int len, unsigned rem) { LL *cache_ptr = nullptr; if (limit == POW10[len]) cache_ptr = &cache[len][rem]; if (cache_ptr && *cache_ptr != -1) return *cache_ptr; LL res = 0; if (len == 0) { res = 1; FOR(digit, 1, 9) { res = res && ((allowed_digits >> digit)&1u) == (rem % digit == 0); } } else { FOR(digit, 1, 9) { if ((allowed_digits & (1u << digit)) == 0) continue; LL limit2 = limit - digit * POW10[len-1]; unsigned rem2 = (10u * rem + digit) % PERIOD; if (limit2 > 0) { res += below_len(allowed_digits, min(limit2, POW10[len-1]), len-1, rem2); } } } if (cache_ptr) *cache_ptr = res; return res; } LL between(LL limit1, LL limit2) { LL res = 0; for (unsigned allowed_digits = 0; allowed_digits < (1u << 10); allowed_digits += 2u) { FOR(len, 0, MAX_LEN) REP(p, PERIOD) cache[len][p] = -1; for (int len=1; limit2 > POW10[len-1]; ++len) { res += below_len(allowed_digits, min(limit2, POW10[len]), len, 0); res -= below_len(allowed_digits, min(limit1, POW10[len]), len, 0); } } return res; } int main() { cin.tie(nullptr); ios::sync_with_stdio(false); calc_pow10(); LL a, b; cin >> a >> b; LL res = between(a, b+1); cout << res << "\n"; } |