reference:http://blog.youkuaiyun.com/lvshubao1314/article/details/43907225
思路:略。
# include <stdio.h>
# include <string.h>
# define LL long long
# define MOD 2520
LL a[21], index[2521], dp[21][MOD][50];
void init()
{
int num = 0;
for(int i=1; i<=MOD; ++i)
if(!(MOD%i))
index[i] = num++;//最小公倍数离散化,优化内存。
}
int gcd(int a, int b)
{
if(b==0) return a;
return gcd(b, a%b);
}
int lcm(int a, int b)
{
return a/gcd(a, b)*b;
}
LL dfs(int pos, int sum, int prelcm, bool limit)
{
if(pos == -1) return sum%prelcm==0;
if(!limit && dp[pos][sum][index[prelcm]] != -1) return dp[pos][sum][index[prelcm]];
int up = limit?a[pos]:9;
LL ans = 0;
for(int i=0; i<=up; ++i)
{
int newsum = (sum*10+i)%MOD;//2520为1~9的最小公倍数,数值对2520取余,如果该数(比2520大)能被其各位数整除,则它一定能被2520整除。
int newlcm = prelcm;
if(i)
newlcm = lcm(newlcm, i);
ans += dfs(pos-1, newsum, newlcm, limit&&(i==a[pos]));
}
if(!limit)
dp[pos][sum][index[prelcm]] = ans;
return ans;
}
LL solve(LL num)
{
int len = 0;
while(num)
{
a[len++] = num%10;
num /= 10;
}
return dfs(len-1, 0, 1, true);
}
int main()
{
LL n, m;
int t;
init();
memset(dp, -1, sizeof(dp));
scanf("%d",&t);
while(t--)
{
scanf("%I64d%I64d",&n,&m);
printf("%I64d\n",solve(m)-solve(n-1));
}
return 0;
}