首先我是想把题目分成好几部分来做 首先是第一部分 列如88897 我们找到它的最高位 然后先把10000以下的算出来 如何去算呢 分成两部分 一部分是 没有0的 一部分是有0的 有0这一部分用dp + map就可以了因为 最多组成的乘积有 9^9 / 9! 为1000多一点 所以开map是完全没问题的 没有0的部分用容斥的思想 就是全部数减掉 每位都>=1 的情况
因为我们这个是只能在整数部分 就是后面每位都可以取到9的情况 我们不妨从前往后 把每一位的小一位取出来 去求 数量 最后统计一下即可
#include<iostream>
#include<unordered_map>
using namespace std;
typedef long long ll;
const int N = 1e5 + 10;
unordered_map<ll,ll>mp[25];
ll b[N];
ll qpow(ll a,ll b){
ll s = 1;
while(b){
if(b & 1) s = s * a;
a = a * a;
b >>= 1;
}
return s;
}
int main(){
ll n,m;
cin >> n >> m;
ll s = n,dig = 0;
while(s){
s /= 10;
dig++;
}
ll sum = 0,cnt = 0;
for(ll i = 1; i <= 9; i++){
if(!mp[1][i] && i <= m){
b[++cnt] = i;
mp[1][i] = 1;
sum += 1;
}
}
for(ll i = 2; i <= dig - 1; i++){
ll sb = cnt;
for(ll j = 1; j <= sb; j++){
for(ll k = 1; k <= 9; k++){
if(!mp[i - 1][b[j] * k] && !mp[i][b[j] * k]){
if(b[j] * k <= m){
sum += mp[i - 1][b[j]];
b[++cnt] = b[j] * k;
mp[i][b[j] * k] += mp[i - 1][b[j]];
}
}else{
if(b[j] * k <= m){
mp[i][b[j] * k] += mp[i - 1][b[j]];
sum += mp[i - 1][b[j]];
}
}
}
//cout << i << " " << b[j] << " " << mp[i][b[j]] <<endl;
}
}
for(ll i = dig; i >= 2; i--){
sum += 9 * qpow(10,i - 2) - qpow(9,i - 1);
//cout << i - 1 << " " << 9 * qpow(10,i - 2) - qpow(9,i - 1) << "Asd" <<endl;
}
/*cout <<sum << endl;
for(int i = 1; i <= cnt; i++){
cout <<b[i] << ' ' << mp[1][b[i]] << endl;
}*/
mp[0][1] = 1;
s = 1;
for(ll i = dig; i >= 1; i--){
//cout << sum << endl;
if(s == 0){
sum += n % qpow(10,i);
break;
return 0;
}
for(ll j = ((n / qpow(10,i - 1)) % 10) - 1; j >= 1; j--){
for(ll k = 1; k <= cnt; k++){
if(b[k] * s * j <= m){
//cout << i << " " << j << " " << b[k] <<" " << mp[i - 1][b[k]] << "ASDA" << endl;
sum += mp[i - 1][b[k]];
}
}
}
if(i != dig && ((n / qpow(10,i - 1)) % 10) >= 1) sum += (((n / qpow(10,i - 1)) % 10)) * qpow(10,i - 1) - (((n / qpow(10,i - 1)) % 10) - 1) * qpow(9,i - 1);
if(i == dig && ((n / qpow(10,i - 1)) % 10) >= 2) sum += (((n / qpow(10,i - 1)) % 10) - 1) * qpow(10,i - 1) - (((n / qpow(10,i - 1)) % 10) - 1) * qpow(9,i - 1);
//cout <<sum << "TTT" <<endl;
s *= ((n / qpow(10,i - 1)) % 10);
// cout <<s <<"GG"<< endl;
}
if(s <= m) sum++;
cout << sum << endl;
/*int ss = 0;
for(int i = 1; i <= n; i++){
int s = i,g = 1;
while(s){
g *= s % 10;
s /= 10;
}
if(g <= m) ss++;
}
cout << ss << "Asd" << endl;*/
return 0;
}