【bzoj2393】Cirno的完美算数教室 数论容斥

Description

~Cirno发现了一种baka数,这种数呢~只含有2和⑨两种数字~~
现在Cirno想知道~一个区间中~~有多少个数能被baka数整除~
但是Cirno这么天才的妖精才不屑去数啦
只能依靠聪明的你咯。

Input

一行正整数L R
( 1 < L < R < 10^10)

Output

一个正整数,代表所求的答案

Sample Input

1 100

Sample Output

58

HINT

此题数据范围应该是10^9

 

题解:

  处理处所有数然后容斥。

 1 #include<cstring>
 2 #include<cmath>
 3 #include<algorithm>
 4 #include<iostream>
 5 #include<cstdio>
 6 
 7 #define ll long long
 8 using namespace std;
 9 inline int read()
10 {
11     int x=0,f=1;char ch=getchar();
12     while(ch>'9'||ch<'0'){if (ch=='-') f=-1;ch=getchar();}
13     while(ch<='9'&&ch>='0'){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}
14     return x*f;
15 }
16 
17 int L,R;
18 int n,m,ans;
19 ll a[2001],b[2001];
20 bool vis[2001];
21 
22 void pre(ll x,int R)
23 {
24     if (x>R) return;
25     if (x) a[++m]=x;
26     pre(x*10+2,R);pre(x*10+9,R);
27 }
28 ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
29 void dfs(int x,int y,ll z)
30 {
31     if (x>n)
32     {
33         if (y&1) ans+=R/z-(L-1)/z;
34         else if (y) ans-=R/z-(L-1)/z;
35         return;
36     }
37     if (z>R) return;
38     dfs(x+1,y,z);
39     z=z/gcd(a[x],z)*a[x];
40     dfs(x+1,y+1,z);
41 }
42 int main()
43 {
44     L=read();R=read();
45     pre(0LL,R);
46     sort(a+1,a+m+1);
47     for (int i=1;i<=m;i++)
48         if (!vis[i])
49         {
50                b[++n]=a[i];
51             for (int j=i+1;j<=m;j++)if (a[j]%a[i]==0) vis[j]=1;
52         }
53     for (int i=1;i<=n;i++)
54         a[n-i+1]=b[i];
55     dfs(1,0,1);
56     printf("%d",ans);
57 }

 

posted @ 2017-12-29 10:05  Kaiser-  阅读(191)  评论(0编辑  收藏  举报