Volodya is an odd boy and his taste is strange as well. It seems to him that a positive integer number is beautiful if and only if it is divisible by each of its nonzero digits. We will not argue with this and just count the quantity of beautiful numbers in given ranges.
The first line of the input contains the number of cases t (1 ≤ t ≤ 10). Each of the next t lines contains two natural numbers li and ri (1 ≤ li ≤ ri ≤ 9 ·1018).
Please, do not use %lld specificator to read or write 64-bit integers in C++. It is preffered to use cin (also you may use %I64d).
Output should contain t numbers — answers to the queries, one number per line — quantities of beautiful numbers in given intervals (from li to ri, inclusively).
1
1 9
9
1
12 15
2
Question link: http://codeforces.com/problemset/problem/55/D
question is
to find the number B in the interval [l,r]: the number is divisible by each of its digits.
If the analysis
is divisible by each digit, it is divisible by the lcm (least common multiple) of the digits in all digits. And the lcm of 1 to 9 is 2520, so we can perform digit dp. When dp[i][j][k] represents the i-th digit,
the number is j, and the lcm of each previous digit is k. But obviously, the value j cannot be directly represented, and we have to find a way to optimize it. Because the essence of recursion to the end is to find x%lcm, then we can think of a property:
x%m==x%(km)%m, in this way, x%lcm==x%2520%lcm, so the second dimension is reduced to within 2520. Now the space complexity is 20*2520*2520, which is still an explosion. Think about where to optimize?
Suddenly found that there are not so many real LCMs, only 48. At this point, the space complexity has become 20*2520*50, and the next step is to solve the recursive memorization, pay attention to the boundary conditions.
See code for details
#include<iostream> #include<cstdio> #include<cmath> #include<cstdlib> #include<algorithm> #include<cstring> #include<queue> #include<vector> #include<bitset> #include<map> #include<deque> #include<stack> using namespace std; typedef pair<int,int> pii; #define X first #define Y second #define pb push_back #define mp make_pair typedef long long ll; #define ms(a,b) memset(a,b,sizeof(a)) const int inf = 0x3f3f3f3f; const int maxn = 1e5+5; const int mod = 1e9+7; const int mm = 2520; #define lson l,m,2*rt #define rson m+1,r,2*rt+1 ll dp[20][2550][50]; int has[2550]; int bit[20]; ll gcd(ll a,ll b){ return (b==0)?a:gcd(b,a%b); } ll lcm(ll a,ll b){ return a/gcd(a,b)*b; } void init(){ int tot=0; for(int i=1;i<2550;i++){ if(mm%i==0){ has [i] = all ++ ; } } } ll dfs( int pos, int preSum, int preLcm, bool limit){ if (pos< 0 ) return preSum%preLcm== 0 ; // to the last digit if (!limit && dp[pos][preSum][has [preLcm]]!=- 1 ) return dp[pos][preSum][has[preLcm]]; // memoization ll ans= 0 ; int ed = limit?bit[pos]: 9 ; // this bit has bounds for ( int i= 0 ;i<=ed;i++ ){ int nowSum = (preSum*10+i)%mm; int nowLcm = preLcm; if(i) nowLcm = lcm(nowLcm,i); ans += dfs(pos-1,nowSum,nowLcm,limit && i==ed); } if(!limit) dp[pos][preSum][has[preLcm]]=ans; return ans; } ll solve(ll x){ int tot=0; while(x){ bit [all ++] = x% 10 ; x/=10; } return dfs(tot-1,0,1,1); } int main(){ #ifdef LOCAL freopen("in.txt","r",stdin); #endif // LOCAL int t; ll l,r; ms(dp,-1); init(); scanf("%d",&t); while(t--){ cin>>l>>r; cout<<solve(r)-solve(l-1)<<endl; } return 0; }