• [SCOI2010]幸运数字


    题目背景

    四川NOI省选2010

    题目描述

    在中国,很多人都把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:
    1 10
    输出样例#1:
    2

    说明

    对于30%的数据,保证1<=a<=b<=1000000

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

    思路:打表+容斥原理+剪枝

    先打一张幸运数字的表;

    然后容斥原理求值;

    剪枝:有些(是前面的幸运数字的倍数)幸运数字是无用的。

    从大到小排。

    超出边界的最小公倍数是无用的。

    代码实现:

     1 #include<cstdio>
     2 #include<algorithm>
     3 #define LL long long
     4 using namespace std;
     5 LL l,r,ans;
     6 LL a,b;
     7 LL s[3000],ss;
     8 LL fs[3000],fss;
     9 LL lch,ret;
    10 char ch[30];
    11 LL read(){
    12     while(ch[0]=getchar(),ch[0]<'0'||ch[0]>'9');
    13     lch=1,ret=ch[0]-'0';
    14     while(ch[lch]=getchar(),ch[lch]>='0'&&ch[lch]<='9') ret=ret*10+ch[lch]-'0',lch++;
    15     return ret;
    16 }
    17 void write(LL x){
    18     if(!x) return;
    19     write(x/10);
    20     putchar(x%10+'0');
    21 }
    22 void dfs(LL x){
    23     if(x>r) return;
    24     if(x) s[ss++]=x;
    25     dfs(x*10+6);
    26     dfs(x*10+8);
    27 }
    28 inline LL gcd(LL x,LL y){return y?gcd(y,x%y):x;}
    29 void get_ans(LL k,LL x,LL y){
    30     if(x>r) return;
    31     if(k) ans+=(k&1)?r/x-(l-1)/x:(l-1)/x-r/x;
    32     for(LL i=y;i<ss;i++){
    33         LL t=x/gcd(x,s[i]);
    34         if(t<=r/s[i]) get_ans(k+1,t*s[i],i+1);
    35     }
    36 }
    37 int main(){
    38     freopen("luckynumber.in","r",stdin);
    39     freopen("luckynumber.out","w",stdout);
    40     l=read(),r=read();
    41     dfs(0);
    42     sort(s,s+ss);
    43     for(LL i=0;i<ss;i++){
    44         for(LL j=0;j<fss;j++)
    45         if(s[i]%fs[j]==0){s[i]=0;break;}
    46         if(s[i]) fs[fss++]=s[i];
    47     }
    48     ss=fss;
    49     for(int i=0;i<ss;i++) s[i]=fs[ss-i-1];
    50     get_ans(0,1,0);
    51     if(!ans) putchar('0');
    52     write(ans);
    53     putchar('
    ');
    54     return 0;
    55 }
    bzoj 74 1950429 J_william
    872 KB 672 MS 1188 B 2017-03-26 18:04:28

    LONG LONG 真恶心!

    题目来源:洛谷,bzoj

  • 相关阅读:
    盒子阴影——Box-shadow
    Flex布局
    常用正则表达式
    选择器
    上传头像功能
    利用百度地图API获取用户浏览器所在省市区
    Android Studio编译运行卡慢的解决方案
    Laravel5.5 解决时区设置差8个小时解决办法
    Git:远程代码与本地冲突常见解决方法
    vue-element-admin解决跨域问题
  • 原文地址:https://www.cnblogs.com/J-william/p/6623475.html
Copyright © 2020-2023  润新知