一开始以为是数位dp
然后发现不可做,因为每一位不固定,然后就想到了dfs枚举,会TLE
令x记录当前已经枚举到了第几个数,y记录已经选了几个数,z表示这几个数的最小公倍数
剪枝:当最小公倍数大于上界r时返回
代码
//By AcerMo
#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define lli long long int
using namespace std;
int n,m;
bool vis[100010];
lli l,r,ans,a[100010],b[100010];
inline void get(int x,lli y)
{
if (y>r) return;
if (x>0) a[++m]=y;
get(x+1,y*10+6);
get(x+1,y*10+8);
return ;
}
inline lli gcd(lli a,lli b)
{
if (!b) return a;
return gcd(b,a%b);
}
inline void dfs(int x,int y,lli z)
{
if (x<1)
{
if (y&1) ans+=(r/z-(l-1)/z);
else if (y) ans-=(r/z-(l-1)/z);
return ;
}
dfs(x-1,y,z);
lli d=z/gcd(a[x],z);
if ((double)a[x]*d<=r) dfs(x-1,y+1,a[x]*d);
return ;
}
int main()
{
cin>>l>>r;
get(0,0);sort(a+1,a+1+m);
for (int i=1;i<=m;i++)
if (!vis[i])
{
for (int j=i+1;j<=m;j++)
if (a[j]%a[i]==0) vis[j]=1;
a[++n]=a[i];
}
dfs(n,0,1);cout<<ans;
return 0;
}