# codeforces 55D beautiful number [数学+数位DP]【动态规划+数论】

——————————-.
D. Beautiful numbers
time limit per test4 seconds
memory limit per test256 megabytes
inputstandard input
outputstandard output
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.

Input
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 ·10^18).

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
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).

Examples
input
1
1 9
output
9
input
1
12 15
output
2
———————————.

mod = (mod*10+本位数字)%2520 ;

dp[位数][x%2520][lcm{xi}];

1 2 3 4 5 6 7 8 9 10 12 14 15 18 20 21 24 28 30 35 36 40 42 45 56 60 63 70 72 84 90 105 120 126 140 168 180 210 252 280 315 360 420 504 630 840 1260 2520

————————————.

#include <bits/stdc++.h>
using namespace std;
#define lalal puts("*****");

typedef long long LL;
const int MOD  = 1000000007;
const int maxn = 200010;

int  num[30],len;
LL  dp[30][2550][50];
int a[50],has[2520];

//x%2520%lcm == 0
int gcd(int a,int b)
{
if(!b) return a;
else return gcd(b,a%b);
}

int llcm(int a,int b)
{
return a/gcd(a,b)*b;
}

LL dfs(int pos,int mod,int lcm,int limit)
{

if(pos<0) return mod%lcm==0;

if(!limit&&dp[pos][mod][has[lcm]]!=-1)
{
//          lalal;
return dp[pos][mod][has[lcm]];
}

int endi = 9;
if(limit) endi = num[pos];

LL res = 0;
int tlcm ;
for(int i=0; i<=endi; i++)
{
if(!i) tlcm = lcm;
else   tlcm = llcm(lcm,i);
res += dfs(pos-1,(mod*10+i)%2520,tlcm,limit&&(i==endi));
}

if(!limit) dp[pos][mod][has[lcm]] = res;
return res;
}

LL solve(LL n)
{
len = 0;

while(n)
{
num[len++] = n%10;
n /= 10;
}

return dfs(len-1,0,1,1);
}

void init()
{
memset(has,0,sizeof(has));
int tem ;
for(int i=0;i<(1<<9);i++)
{
tem = 1;
for(int j=1;j<=9;j++)
{
if(i&(1<<j))
tem = llcm(tem,j+1);
}
has[tem]=1;
}

int l = 0;
for(int i=0;i<=2520;i++)
if(has[i]) a[l]=i,has[i]=l++;

/*
for(int i=0;i<l;i++)  printf("%d %d\n",has[a[i]],a[i]);
puts("");
printf("%d\n",l);
*/

}

int main()
{
// printf("%d\n",2520*2520);
init();
memset(dp,-1,sizeof(dp));

int _;
scanf("%d",&_);
while(_--)
{
LL n,m;
scanf("%I64d%I64d",&m,&n);
//cout <<n<<"  "<<m<<endl;
// printf("%I64d %I64d\n",solve(n),solve(m-1));

printf("%I64d\n",solve(n)-solve(m-1));
}
return 0;
}



08-28 38
10-11 574
11-09 722
06-24 406
04-22 685
06-07 446
02-08 1581
07-12 352
04-28 1366
05-15 474
©️2020 CSDN 皮肤主题: 技术黑板 设计师:CSDN官方博客