学一发数位DP
如果直接记录乘积的话有
109
的情况,但是因为每一位只有1~9,所以最后乘积只有2 3 5 7的质因数,那么把在第i为放0~9转化成放入多少个2 3 5 7
f(i,c2,c3,c5,c7,j)
表示转移到从高到低的第i位,因数2的个数为c2,3的个数为c3,5的个数为c5,7的个数为c7,j表示到i位的数字是否等于R的,然后转移一下 就好了…
#include <cstdio>
#include <cstring>
#include <string>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long ll;
int n;
int w[20],wt;
int add[10][5];
ll f[2][32][21][14][13][2];
ll p2[32],p3[21],p5[14],p7[13];
ll L,R;
inline ll solve(ll lt,int n){
memset(f,0,sizeof(f));
int k=0; wt=0; ll x=lt,ret=0;
while(x) w[++wt]=x%10,x/=10;
for(int i=1;i<=w[wt];i++)
if(i>n) break; else
if(i==w[wt]) f[0][add[i][1]][add[i][2]][add[i][3]][add[i][4]][1]=1;
else f[0][add[i][1]][add[i][2]][add[i][3]][add[i][4]][0]=1;
for(int j=wt-1;j;j--){
k^=1;
for(int i=1;i<=9;i++)
if(i<=n) f[k][add[i][1]][add[i][2]][add[i][3]][add[i][4]][0]=1;
for(int i1=0;i1<=30;i1++)
if(p2[i1]<=n)
for(int i2=0;i2<=19;i2++)
if(p3[i2]*p2[i1]<=n)
for(int i3=0;i3<=13;i3++)
if(p5[i3]*p3[i2]*p2[i1]<=n)
for(int i4=0;i4<=11;i4++)
if(p7[i4]*p2[i1]*p3[i2]*p5[i3]<=n){
ll now=p2[i1]*p3[i2]*p5[i3]*p7[i4];
for(int i=1;i<=9;i++){
if(i*now>n) break;
f[k][i1+add[i][1]][i2+add[i][2]][i3+add[i][3]][i4+add[i][4]][0]+=f[k^1][i1][i2][i3][i4][0];
if(i>w[j]) continue;
if(i<w[j]) f[k][i1+add[i][1]][i2+add[i][2]][i3+add[i][3]][i4+add[i][4]][0]+=f[k^1][i1][i2][i3][i4][1];
else f[k][i1+add[i][1]][i2+add[i][2]][i3+add[i][3]][i4+add[i][4]][1]+=f[k^1][i1][i2][i3][i4][1];
}
}
for(int i1=0;i1<=30;i1++)
for(int i2=0;i2<=19;i2++)
for(int i3=0;i3<=13;i3++)
for(int i4=0;i4<=11;i4++)
f[k^1][i1][i2][i3][i4][0]=f[k^1][i1][i2][i3][i4][1]=0;
}
for(int i1=0;i1<=30;i1++)
for(int i2=0;i2<=19;i2++)
for(int i3=0;i3<=13;i3++)
for(int i4=0;i4<=11;i4++)
ret+=f[k][i1][i2][i3][i4][0],f[k][i1][i2][i3][i4][0]=f[k][i1][i2][i3][i4][1]=0;
return ret;
}
int main(){
cin>>n>>L>>R;
p2[0]=p3[0]=p5[0]=p7[0]=1;
for(int i=1;i<=30;i++) p2[i]=p2[i-1]*2;
for(int i=1;i<=19;i++) p3[i]=p3[i-1]*3;
for(int i=1;i<=13;i++) p5[i]=p5[i-1]*5;
for(int i=1;i<=11;i++) p7[i]=p7[i-1]*7;
add[2][1]=1; add[3][2]=1; add[4][1]=2; add[5][3]=1;
add[6][1]=1; add[6][2]=1; add[7][4]=1; add[8][1]=3;
add[9][2]=2;
cout<<solve(R,n)-solve(L,n)<<endl;
return 0;
}