P2567 [SCOI2010]幸运数字 DFS+容斥定理

Posted liylho

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了P2567 [SCOI2010]幸运数字 DFS+容斥定理相关的知识,希望对你有一定的参考价值。

P2567 [SCOI2010]幸运数字

题目描述

在中国,很多人都把6和8视为是幸运数字!lxhgww也这样认为,于是他定义自己的“幸运号码”是十进制表示中只包含数字6和8的那些号码,比如68,666,888都是“幸运号码”!但是这种“幸运号码”总是太少了,比如在[1,100]的区间内就只有6个(6,8,66,68,86,88),于是他又定义了一种“近似幸运号码”。lxhgww规定,凡是“幸运号码”的倍数都是“近似幸运号码”,当然,任何的“幸运号码”也都是“近似幸运号码”,比如12,16,666都是“近似幸运号码”。

现在lxhgww想知道在一段闭区间[a, b]内,“近似幸运号码”的个数。

输入输出格式

输入格式:

 

输入数据是一行,包括2个数字a和b

 

输出格式:

 

输出数据是一行,包括1个数字,表示在闭区间[a, b]内“近似幸运号码”的个数

 

输入输出样例

输入样例
1 10
输出样例
2

说明

对于100%的数据,保证1<=a<=b<=10000000000

思路:

代码:

 1 //#include"bits/stdc++.h"
 2 #include <sstream>
 3 #include <iomanip>
 4 #include"cstdio"
 5 #include"map"
 6 #include"set"
 7 #include"cmath"
 8 #include"queue"
 9 #include"vector"
10 #include"string"
11 #include"cstring"
12 #include"time.h"
13 #include"iostream"
14 #include"stdlib.h"
15 #include"algorithm"
16 #define db double
17 #define ll long long
18 #define vec vector<ll>
19 #define mt  vector<vec>
20 #define ci(x) scanf("%d",&x)
21 #define cd(x) scanf("%lf",&x)
22 #define cl(x) scanf("%lld",&x)
23 #define pi(x) printf("%d\n",x)
24 #define pd(x) printf("%f\n",x)
25 #define pl(x) printf("%lld\n",x)
26 //#define rep(i, x, y) for(int i=x;i<=y;i++)
27 #define rep(i,n) for(int i=0;i<n;i++)
28 const int N   = 1e5 + 5;
29 const int mod = 1e9 + 7;
30 const int MOD = mod - 1;
31 const int inf = 0x3f3f3f3f;
32 const db  PI  = acos(-1.0);
33 const db  eps = 1e-10;
34 using namespace std;
35 ll a[N],b[N];
36 bool v[N];
37 int m=0,n=0;
38 ll l,r,ans=0;
39 ll gcd(ll x,ll y){
40     return y==0?x:gcd(y,x%y);
41 }
42 void init(ll x){
43     if(x>r) return ;
44     else if(x>0) a[++m]=x;//0不加入
45     init(x*10+6);
46     init(x*10+8);
47 }
48 void dfs(int x,int y,ll z)//表示:前x个数字中选y个数字时的lcm为z
49 {
50     if(x==n){
51         if(y&1) ans+=r/z-(l-1)/z;//奇数加
52         if(y%2==0&&y!=0)    ans-=r/z-(l-1)/z;//偶数减
53         return;
54     }
55     dfs(x+1,y,z);
56     ll s=z/gcd(a[x+1],z);
57     if((db(s)*a[x+1])<=r) dfs(x+1,y+1,a[x+1]*s);//一个剪枝:lcm<=r
58 }
59 int main()
60 {
61     cl(l),cl(r);
62     init(0);
63     sort(a+1,a+m+1);
64     for(int i=1;i<=m;i++){//去掉内部倍数情况
65         if(!v[i]){
66             b[++n]=a[i];
67             for(int j=i+1;j<=m;j++)
68                 if(a[j]%a[i]==0) v[j]=1;
69         }
70     }
71     for(int i=1;i<=n;i++) a[n+1-i]=b[i];//数字从大到小排
72     dfs(0,0,1);
73     pl(ans);
74     return 0;
75 }

 

以上是关于P2567 [SCOI2010]幸运数字 DFS+容斥定理的主要内容,如果未能解决你的问题,请参考以下文章

BZOJ1853/2393[Scoi2010]幸运数字/Cirno的完美算数教室 DFS+容斥

BZOJ1853 SCOI2010 幸运数字 DFS+容斥原理

bzoj1853: [Scoi2010]幸运数字

BZOJ1853: [Scoi2010]幸运数字

1853[Scoi2010]幸运数字 容斥

bzoj1853SCOI2010幸运数字