【数据范围】
对于30%的数据,保证1 < =a < =b < =1000000
对于100%的数据,保证1 < =a < =b < =10000000000
Day1
题解:同BZOJ 2393
需要注意在求lcm的过程中可能爆long long ,计算过程需要用double
再就是需要对幸运数字从大到小排序,因为这样很快就会超过r,能减少一些不必要的搜索过程,否则可能会TLE
#include<iostream> #include<cstdio> #include<cmath> #include<cstring> #include<algorithm> #define N 100000 #define ll long long using namespace std; ll l,r,a[N],b[N],vis[N],c[N]; ll ans; int n,m,cnt; void get_num(ll x) { if (x>r) return; if (x) a[++cnt]=x; get_num(x*10+8); get_num(x*10+6); } ll gcd(ll x,ll y) { ll r; while (y!=0) { r=x%y; x=y; y=r; } return x; } void dfs(int x,int y,ll lcm) { if (x>n) { if (y&1) ans+=r/lcm-(l-1)/lcm; else if (y) ans-=r/lcm-(l-1)/lcm; return; } dfs(x+1,y,lcm); double t=(double)lcm*b[x]/(double)gcd(lcm,b[x]); if (t<=r) { ll k=(ll)t; dfs(x+1,y+1,k); } } int main() { scanf("%lld%lld",&l,&r); get_num(0); sort(a+1,a+cnt+1); for (int i=1;i<=cnt;i++) if (!vis[i]) { c[++n]=a[i]; for (int j=i;j<=cnt;j++) if (!(a[j]%a[i])) vis[j]=1; } for (int i=1;i<=n;i++) b[n-i+1]=c[i]; dfs(1,0,1); printf("%lld\n",ans); return 0; }