[题目描述]
Submit: 703 Solved: 418
[ Submit][ Status][ Discuss]
Description
~Cirno
发现了一种
baka
数,这种数呢
~
只含有
2
和⑨两种数字
~~
现在
Cirno
想知道
~
一个区间中
~~
有多少个数能被
baka
数整除
~
但是
Cirno
这么天才的妖精才不屑去数啦
只能依靠聪明的你咯。
Input
一行正整数
L R
( 1 < L < R < 10^10)
Output
一个正整数,代表所求的答案
Sample Input
1 100
Sample Output
58
[题解]
暴力容斥一发,T飞。。。
加了两个剪枝跑得飞快 1.在容斥时若i是j的倍数,则i是无效的。直接跳过
2.dfs时从大的往小的做,可以尽早跳出许多非法状态。
/* --------------
user Vanisher
problem bzoj-2393
----------------*/
# include <bits/stdc++.h>
# define ll long long
# define N 10010
using namespace std;
ll num,p[N],ans,r,l,f[N];
ll read(){
ll tmp=0, fh=1; char ch=getchar();
while (ch<'0'||ch>'9'){if (ch=='-') fh=-1; ch=getchar();}
while (ch>='0'&&ch<='9'){tmp=tmp*10+ch-'0'; ch=getchar();}
return tmp*fh;
}
ll gcd(ll x, ll y){
if (x%y==0) return y;
else return gcd(y,x%y);
}
bool cmp(ll x, ll y){ return x>y;}
void solve(ll k, ll tag, ll sum){
if (k>num){
if (tag==0) return;
if (tag%2==1) ans=ans+r/sum-(l-1)/sum;
else ans=ans-r/sum+(l-1)/sum;
return;
}
solve(k+1,tag,sum);
ll t=gcd(sum,p[k]);
if (r/(sum/t)>=p[k]) solve(k+1,tag+1,sum/t*p[k]);
}
int main(){
l=read(); r=read();
p[0]=0; ll pl=0, pr=0;
while (pl<=pr){
ll x=p[pl++];
if (x*10+2<=r) p[++pr]=x*10+2;
if (x*10+9<=r) p[++pr]=x*10+9;
}
num=pr;
for (int i=1; i<=num; i++){
f[i]=true;
for (int j=1; j<i; j++) if (p[i]%p[j]==0) {f[i]=false; break;}
}
int k=0;
for (int i=1; i<=num; i++)
if (f[i]==true) p[++k]=p[i];
num=k;
sort(p+1,p+num+1,cmp);
solve(1,0,1);
cout<<ans<<endl;
return 0;
}