BZOJ1853: [Scoi2010]幸运数字

Posted SummerSky

tags:

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

1853: [Scoi2010]幸运数字

Description

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

Input

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

Output

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

Sample Input

【样例输入1】
1 10
【样例输入2】
1234 4321

Sample Output

【样例输出1】
2
【样例输出2】
809

HINT

【数据范围】
对于30%的数据,保证1 < =a < =b < =1000000
对于100%的数据,保证1 < =a < =b < =10000000000

Source

Day1

 

这题看到,10^10次一脸操逼,容斥原理可是2^x次的时间啊,

这里少说也有2^10次的幸运号码,就算除掉一些倍数还有很多,

而且算一下乘起来的数,绝对要爆long long,这时一个必要的剪枝就出现了。

如果两数的lcm大于b就把他日掉,而且不能用long long要用long double

就写成这样:if ((long double)x/t<=(long double)r/y)dfs2(k+1,x/t*y,kk*(-1));

技术分享
 1 #include<iostream>
 2 #include<algorithm>
 3 #include<cstdio>
 4 #include<cstring>
 5 #include<cmath>
 6 #include<cstdlib>
 7 using namespace std;
 8 typedef long long ll;
 9 typedef long double ld;
10 typedef pair<int,int> pr;
11 const double pi=acos(-1);
12 #define rep(i,a,n) for(int i=a;i<=n;i++)
13 #define per(i,n,a) for(int i=n;i>=a;i--)
14 #define Rep(i,u) for(int i=head[u];i;i=Next[i])
15 #define clr(a) memset(a,0,sizeof a)
16 #define pb push_back
17 #define mp make_pair
18 #define fi first
19 #define sc second
20 ld eps=1e-9;
21 ll pp=1000000007;
22 ll mo(ll a,ll pp){if(a>=0 && a<pp)return a;a%=pp;if(a<0)a+=pp;return a;}
23 ll powmod(ll a,ll b,ll pp){ll ans=1;for(;b;b>>=1,a=mo(a*a,pp))if(b&1)ans=mo(ans*a,pp);return ans;}
24 ll read(){
25 ll ans=0;
26 char last= ,ch=getchar();
27 while(ch<0 || ch>9)last=ch,ch=getchar();
28 while(ch>=0 && ch<=9)ans=ans*10+ch-0,ch=getchar();
29 if(last==-)ans=-ans;
30 return ans;
31 }
32 //head
33 int n,m;
34 ll a[5000],b[5000],ans,l,r;
35 void dfs1(ll x){
36     if (x>r) return;
37     if (x)a[++n]=x;
38     dfs1(x*10+6);
39     dfs1(x*10+8);
40 }
41 void dfs2(int k,ll x,int kk){
42     if (k==m+1){
43         if (x==1) return;
44         ans+=(r/x-(l-1)/x)*kk;
45         return;
46     }
47     dfs2(k+1,x,kk);
48     ll y=b[k];
49     ll t=__gcd(y,x);
50     if ((long double)x/t<=(long double)r/y)dfs2(k+1,x/t*y,kk*(-1));
51 }
52 int main()
53 {
54     l=read(),r=read();
55       dfs1(0);
56       sort(a+1,a+n+1);
57       for (int i=1;i<=n;i++){
58           int pf=0;
59           for (int j=1;j<=i-1;j++)
60             if (a[i]%a[j]==0)pf=1;
61           if(!pf)b[++m]=a[i]; 
62       }
63     for (int i=1;i<=m/2;i++)swap(b[i],b[m+1-i]);
64     dfs2(1,1,-1);
65     cout<<ans<<endl;
66     return 0;
67 } 
View Code

 

 










以上是关于BZOJ1853: [Scoi2010]幸运数字的主要内容,如果未能解决你的问题,请参考以下文章

BZOJ-1853: [Scoi2010]幸运数字 (容斥原理)

AC日记——[SCOI2010]幸运数字 bzoj 1853

BZOJ 1853 Scoi2010 幸运数字

bzoj1853 [Scoi2010]幸运数字

bzoj1853 [Scoi2010]幸运数字

bzoj1853 [Scoi2010]幸运数字