很容易看出来是数位dp
我们可以发现个位数字乘积的取值并没有特别多,于是可以通过质因数只有
2,3,5,7
2
,
3
,
5
,
7
的性质预处理出每种乘积,可以用map存起来。
#include<bits/stdc++.h>
#define ll long long
using namespace std;
int p[4]={2,3,5,7};
map<int,int> m;
int pt[5211];
ll f[21][5211],n,a,b,tot,c[21];
inline void dfs(ll s,ll st){
for(int i=st;i<4;++i){
if(s*p[i]>n) break;
m[s*p[i]]=++tot;
pt[tot]=s*p[i];
dfs(s*p[i],i);
}
}
ll solve(ll x){
if(x==0) return 0;
ll res=0,l=0,s;
while(x) c[++l]=x%10,x/=10;
for(int j=1;j<l;++j)
for(int i=1;i<=tot;++i)
if(pt[i]<=n) res+=f[j][i];
s=c[l];
for(int i=1;i<c[l];++i)
for(int j=1;j<=tot;++j)
if(i*pt[j]<=n) res+=f[l-1][m[pt[j]]];
for(int i=l-1;i>=2;--i){
for(int k=1;k<c[i];++k)
for(int j=1;j<=tot;++j)
if(s*k*pt[j]<=n) res+=f[i-1][m[pt[j]]];
s*=c[i];if(!s||s>n) break;
}
for(int i=1;i<=c[1];++i)
if(s*i<=n&&s*i) ++res;
return res;
}
int main(){
scanf("%d%lld%lld",&n,&a,&b);
m[1]=++tot;pt[tot]=1;dfs(1,0);
for(int i=1;i<=9&&i<=n;++i) f[1][m[i]]=1;
for(int i=1;i<=17;++i)
for(int j=1;j<=tot;++j)
for(int k=1;k<=9;++k) f[i+1][m[pt[j]*k]]+=f[i][j];
return !printf("%lld",solve(b-1)-solve(a-1));
}