1 #include<cstdio> 2 #include<iostream> 3 #include<queue> 4 #include<algorithm> 5 #define ll long long 6 #define M 40009 7 #define MO 1000000007 8 using namespace std; 9 int a[15],tot,K,anss; 10 ll ans[10*M],n,f[15][M][2],size[M],m; 11 struct data 12 { 13 int x,y; 14 ll z; 15 data(int a1,int a2) 16 { 17 x=a1; 18 y=a2; 19 z=size[x]*size[y]; 20 } 21 bool operator <(data a1)const 22 { 23 return z<a1.z; 24 } 25 }; 26 void dfs(int wei,ll a1,int now) 27 { 28 if(a1>m) 29 return; 30 if(wei==tot) 31 { 32 ans[++ans[0]]=a1; 33 return; 34 } 35 for(int i=now;i<10;i++) 36 dfs(wei+1,a1*i,i); 37 return; 38 } 39 bool cmp(ll a1,ll a2) 40 { 41 return a1>a2; 42 } 43 int main() 44 { 45 scanf("%lld%d",&n,&K); 46 m=n; 47 for(;n;n/=10) 48 a[++tot]=n%10; 49 dfs(0,1,1); 50 sort(ans+1,ans+ans[0]+1); 51 ans[0]=unique(ans+1,ans+ans[0]+1)-ans-1; 52 f[0][1][0]=1; 53 for(int i=0;i<tot;i++) 54 { 55 for(int j=1;j<=ans[0];j++) 56 for(int k=0;k<2;k++) 57 if(f[i][j][k]) 58 for(int l=1;l<10;l++) 59 { 60 ll a1=ans[j]*l; 61 if(a1>ans[ans[0]]) 62 continue; 63 a1=lower_bound(ans+1,ans+ans[0]+1,a1)-ans; 64 f[i+1][a1][(k+l)>a[i+1]]+=f[i][j][k]; 65 } 66 } 67 for(int i=1;i<ans[0];i++) 68 for(int j=1;j<tot;j++) 69 size[i]+=f[j][i][0]+f[j][i][1]; 70 for(int i=1;i<=ans[0];i++) 71 size[i]+=f[tot][i][0]; 72 sort(size+1,size+ans[0]+1,cmp); 73 priority_queue<data> p; 74 p.push(data(1,1)); 75 for(;!p.empty();) 76 { 77 K--; 78 data q=p.top(); 79 p.pop(); 80 anss=(anss+q.z)%MO; 81 if(!K) 82 break; 83 if(q.x!=q.y) 84 { 85 anss=(anss+q.z)%MO; 86 K--; 87 if(!K) 88 break; 89 p.push(data(q.x+1,q.y)); 90 } 91 if(q.x==1) 92 p.push(data(q.x,q.y+1)); 93 } 94 printf("%d",anss); 95 return 0; 96 }
DP求出转移到x坐标的数目。各位数乘积的实际数目少。