【题目分析】
数位DP
【代码】
#include <cstdio>
#include <cstring>
#include <iostream>
#include <cmath>
#include <algorithm>
#define ll long long
using namespace std;
int tt;
int sa[2530],num[21];
ll l,r;
ll dp[21][2520][50];
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;}
inline void init()
{
int cnt=0;
for (int i=1;i<=2520;++i) if (2520%i==0) sa[i]=++cnt;
memset(dp,-1,sizeof dp);
}
inline ll dfs(int pos,int psum,int plcm,bool flag)
{
if (pos==0) return psum%plcm==0;
if (!flag&&dp[pos][psum][sa[plcm]]!=-1)
return dp[pos][psum][sa[plcm]];
int end=flag?num[pos]:9;
ll ans=0;
for (int i=0;i<=end;++i)
{
int nsum=(psum*10+i)%2520;
int nlcm=plcm;
if (i) nlcm=lcm(plcm,i);
ans+=dfs(pos-1,nsum,nlcm,flag&&i==end);
}
if (!flag) return dp[pos][psum][sa[plcm]]=ans;
return ans;
}
inline ll cal(ll x)
{
memset(num,0,sizeof num);
int pos=0;
while (x)
{
num[++pos]=x%10;
x/=10;
}
return dfs(pos,0,1,1);
}
int main()
{
init();
scanf("%d",&tt);
while (tt--)
{
scanf("%I64d%I64d",&l,&r);
printf("%I64d\n",cal(r)-cal(l-1));
}
}