Description
~Cirno
发现了一种
baka
数,这种数呢
~
只含有
2
和⑨两种数字
~~
现在
Cirno
想知道
~
一个区间中
~~
有多少个数能被
baka
数整除
~
但是
Cirno
这么天才的妖精才不屑去数啦
只能依靠聪明的你咯。
Input
一行正整数
L R
( 1 < L < R < 10^10)
Output
一个正整数,代表所求的答案
Sample Input
1 100
Sample Output
58
题解:首先把所有符合条件的数与处理出来,然后去掉这些倍数。
然后我们边搜索边容斥即可,因为几个数最大公约数大于R就没有意义了,所以这样剪枝会很快。
代码:
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#define N 2010
using namespace std;
long long a[N],b[N],vis[N],ans,l,r;
long long gcd(long long a,long long b){return b?gcd(b,a%b):a;}
void pro(long long x){if (x>r) return;a[++a[0]]=x;pro(x*10+2);pro(x*10+9);}
void dfs(int p,int f,long long v){
if(!b[p]){if(v!=1)ans+=(r/v-(l-1)/v)*f;return;}
dfs(p+1,f,v);
long long temp=v*b[p]/gcd(v,b[p]);if(temp>r) return;
dfs(p+1,-f,temp);
}
int main(){
scanf("%lld%lld",&l,&r);pro(2);pro(9);sort(a+1,a+a[0]+1);
for (int i=1;i<a[0];i++)
for (int j=i+1;j<=a[0];j++)
if (a[j]%a[i]==0) vis[j]=1;
for (int i=1;i<=a[0];i++) if (!vis[i]) b[++b[0]]=a[i];
dfs(1,-1,1);
cout<<ans<<endl;
}