山东济南彤昌机械科技有限公司 山东济南江鹏工贸游有限公司

bzoj 2393 Cirno的完美算数教室(容斥原理+搜索)

 

【题意】

 

    定义C数为只包含数字2和9的数,求[L,R]内能被C数整除的个数。

 

【思路】

 

    Dfs预处理出C数,并去除其中倍数的情况。

    Dfs搜索出现情况,奇数加,偶数减,当数值大于R时剪枝。

 

【代码】

 

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 using namespace std;
 5 
 6 typedef long long ll;
 7 const int N = 2e3+10;
 8 
 9 ll a[N],b[N],vis[N],ans,tot,n,L,R;
10 
11 void get_pre(int num)
12 {
13     if(num>R) return ;
14     if(num) a[++tot]=num;
15     get_pre(num*10+2);
16     get_pre(num*10+9);
17 }
18 ll gcd(ll a,ll b)
19 {
20     return b==0? a:gcd(b,a%b);
21 }
22 void dfs(int cur,int cnt,ll lcm)
23 {
24     if(cur==n+1) {
25         if(cnt&1) ans+=R/lcm-(L-1)/lcm;
26         else if(cnt) ans-=R/lcm-(L-1)/lcm;
27         return ;
28     }
29     dfs(cur+1,cnt,lcm);
30     ll val=lcm*a[cur]/(gcd(lcm,a[cur]));
31     if(val<=R) dfs(cur+1,cnt+1,val);
32 }
33 
34 int main()
35 {
36     scanf("%lld%lld",&L,&R);
37     get_pre(0);
38     sort(a+1,a+tot+1);
39     for(int i=1;i<=tot;i++)
40     if(!vis[i]) {
41         b[++n]=a[i];
42         for(int j=i+1;j<=tot;j++)
43             if(a[j]%a[i]==0) vis[j]=1; 
44     }
45     for(int i=1;i<=n;i++)
46         a[i]=b[n-i+1];
47     dfs(1,0,1);
48     printf("%lld\n",ans);
49     return 0;
50 }

 

posted on 2016-03-30 11:37  hahalidaxin  阅读(422)  评论(0编辑  收藏  举报