这两个题是完全一样的,但1853会爆long long,中间要用long double估计一下。
popo大神的题解:http://blog.csdn.net/popoqqq/article/details/41807333
题目大意:求在[L,R]中能被“baka数”整除的数的个数.baka数是数位组成只含2和9(⑨)的数.范围1e10-1e11.
先预处理出所有baka数,再把是另一个的倍数的删去,这里暴力即可.
如果个数少的话显然是一个求lcm的容斥,但复杂度是2^n的
所以这里用搜索+剪枝
还是枚举每个数选与不选,当当前的lcm大于R就剪枝
倒着从大到小枚举也可以加快速度
//BZOJ2393 #include <bits/stdc++.h> #define LL long long #define clr(x,i) memset(x,i,sizeof(x)) using namespace std; const int N=2005; int vist[N],c1,tot; LL l,r,a[N],ans; LL gcd(LL a,LL b) { if(!b)return a; return gcd(b,a%b); } void dfs1(LL x) { if(x>r)return; a[++c1]=x; dfs1(x*10+2);dfs1(x*10+9); } void dfs2(int now,int f,LL x) { if(now==0){ if(x>1) ans+=(r/x-(l-1)/x)*f; return; } dfs2(now-1,f,x); LL lcm=a[now]*x/gcd(a[now],x); if(lcm>r)return;// dfs2(now-1,-f,lcm); } int main() { scanf("%lld%lld",&l,&r); dfs1(2);dfs1(9); sort(a+1,a+c1+1); for(int i=1;i<c1;i++) for(int j=i+1;j<=c1;j++) if(a[j]%a[i]==0)vist[j]=1; for(int i=1;i<=c1;i++) if(!vist[i])a[++tot]=a[i]; dfs2(tot,-1,1); printf("%lld\n",ans); return 0; }