题目描述
题解
和BZOJ2393基本一样
数据范围大一些,需要将b排序先选大的让它尽量剪枝
代码
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
using namespace std;
#define LL long long
LL l,r,ans;
LL a[3005],b[3005];
void get(LL x)
{
if (x>r) return;
a[++a[0]]=x;
get(x*10+6);
get(x*10+8);
}
LL gcd(LL a,LL b)
{
if (!b) return a;
else return gcd(b,a%b);
}
void dfs(int x,int y,LL lcm)
{
if (x==b[0]+1)
{
if (y&1) ans+=r/lcm-(l-1)/lcm;
else if (y) ans-=r/lcm-(l-1)/lcm;
return;
}
dfs(x+1,y,lcm);
LL t=gcd(lcm,b[x]);
lcm/=t;
if (r/lcm<b[x]) return;
lcm*=b[x];
dfs(x+1,y+1,lcm);
}
int main()
{
scanf("%lld%lld",&l,&r);get(0);
sort(a+1,a+a[0]+1);
for (int i=1;i<=a[0];++i)
if (a[i])
{
b[++b[0]]=a[i];
for (int j=i+1;j<=a[0];++j)
if (a[j]%a[i]==0) a[j]=0;
}
for (int i=1;i<=b[0]/2;++i) swap(b[i],b[b[0]-i+1]);
dfs(1,0,1);
printf("%lld\n",ans);
}