zoukankan      html  css  js  c++  java
  • bzoj1853 [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

    正解:搜索+容斥原理。

    首先把所有幸运数搜索出来,最多只会有$2046$个。

    然后我们考虑容斥原理,即暴力枚举每个数用不用,然后加减一下贡献即可。

    但是极限数据跑不过,我们加两个剪枝。

    首先我们把所有幸运数从大到小搜索,这样留给后面的状态就会变少。

    然后我们把是一个幸运数数的倍数的幸运数去掉,可以发现这是不会影响答案的,并且可以减少状态。

    然后注意求$lcm$可能会爆$long long$,我们使用$double$即可。这样我们就能通过此题了。

     1 #include <bits/stdc++.h>
     2 #define il inline
     3 #define RG register
     4 #define ll long long
     5 
     6 using namespace std;
     7 
     8 ll st[5010],ss[5050],vis[5050],tp,top,ans,a,b;
     9 
    10 il ll cmp(const ll &a,const ll &b){ return a>b; }
    11 
    12 il ll gcd(RG ll a,RG ll b){ return b ? gcd(b,a%b) : a; }
    13 
    14 il double lcm(RG ll a,RG ll b){ return 1.0*a/gcd(a,b)*b; }
    15 
    16 il void dfs0(RG ll x,RG ll tot){
    17   if (tot>b) return; if (tot) st[++top]=tot;
    18   dfs0(x+1,tot*10+6),dfs0(x+1,tot*10+8); return;
    19 }
    20 
    21 il void dfs(RG ll x,RG ll tot,RG ll op){
    22   if (x>top){
    23     if (tot==1) return;
    24     if (op) ans+=b/tot-(a-1)/tot;
    25     else ans-=b/tot-(a-1)/tot;
    26     return;
    27   }
    28   dfs(x+1,tot,op); RG double res=lcm(tot,st[x]);
    29   if (res>b) return; dfs(x+1,res,op^1); return;
    30 }
    31 
    32 int main(){
    33 #ifndef ONLINE_JUDGE
    34   freopen("number.in","r",stdin);
    35   freopen("number.out","w",stdout);
    36 #endif
    37   cin>>a>>b,dfs0(1,0);
    38   for (RG int i=1;i<top;++i)
    39     for (RG int j=i+1;j<=top;++j)
    40       if (st[i]%st[j]==0) vis[i]=1;
    41       else if (st[j]%st[i]==0) vis[j]=1;
    42   for (RG int i=1;i<=top;++i) if (!vis[i]) ss[++tp]=st[i];
    43   for (RG int i=1;i<=tp;++i) st[i]=ss[i]; top=tp;
    44   sort(st+1,st+top+1,cmp),dfs(1,1,0),cout<<ans; return 0;
    45 }
  • 相关阅读:
    ZooKeeper的安装和API
    Flume案例Ganglia监控
    二十五、小程序的图片预览(放大滑动)
    二十四、小程序中改变checkbox和radio的样式
    二十三、小程序中的三级下拉框(下拉菜单)
    二十二:制作app的时候超出部分不能滑动
    二十一、当锚点遇到fixed(margin和padding)
    二十:让行内元素在div中垂直居中
    十九、多文件上传(ajaxFileupload实现多文件上传功能)
    十六、字符串和数组之间的转换
  • 原文地址:https://www.cnblogs.com/wfj2048/p/7693605.html
Copyright © 2011-2022 走看看