zoukankan      html  css  js  c++  java
  • [BZOJ1853][Scoi2010]幸运数字 容斥+搜索剪枝

    1853: [Scoi2010]幸运数字

    Time Limit: 2 Sec  Memory Limit: 64 MB
    Submit: 3202  Solved: 1198
    [Submit][Status][Discuss]

    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

    考虑由6和8组成的数很少,枚举。

    之后去掉互为倍数的数。

    把这些数从大到小排序加快搜索增长速度。

    最小公倍数>r时退出。(可能爆long long运用double判断)

    容斥。

     1 #include<iostream>
     2 #include<cstring>
     3 #include<cstdlib>
     4 #include<cstdio>
     5 #include<cmath>
     6 #include<algorithm>
     7 #define LL long long
     8 #define maxn 500005
     9 using namespace std;
    10 LL read() {
    11     LL x=0;char ch=getchar();
    12     for(;!isdigit(ch);ch=getchar()) ;
    13     for(;isdigit(ch);ch=getchar())x=x*10+ch-'0';
    14     return x;
    15 }
    16 LL a[maxn],l,r,tot;
    17 LL gcd(LL x,LL y) {return y==0?x:gcd(y,x%y);}
    18 void make(LL x){
    19     if(x>r) return ;
    20     if(x>0) a[++tot]=x;
    21     make(x*10+6);
    22     make(x*10+8);
    23 }
    24 LL ans=0;
    25 void solve(LL x,LL now,LL val) {
    26     if(x==tot+1) {
    27         if(!now||!val) return;
    28         if(now&1) ans+=r/val-(l-1)/val;
    29         else ans-=r/val-(l-1)/val;
    30         return ;
    31     }
    32     solve(x+1,now,val);
    33     
    34     if(!now){solve(x+1,now+1,a[x]);return;}
    35     LL nn=gcd(val,a[x]);
    36     if((double)a[x]*val/nn>r) return;
    37     solve(x+1,now+1,a[x]*val/nn);
    38 }
    39 int main() {
    40     l=read(),r=read();
    41     make(0);
    42     sort(a+1,a+tot+1);
    43     for(int i=1;i<=tot;i++) {
    44         if(!a[i]) continue;
    45         for(int j=i+1;j<=tot;j++) if(a[j]%a[i]==0) a[j]=0;
    46     }
    47     LL tmp=tot;tot=0;
    48     for(int i=1;i<=tmp;i++) if(a[i]) a[++tot]=a[i];
    49     for(int i=1;i<=tot/2;i++) swap(a[i],a[tot-i+1]);
    50     solve(1,0,0);
    51     printf("%lld
    ",ans);
    52 }
    View Code
  • 相关阅读:
    交换排序------冒泡法 及其优化
    [编程题]最大和子矩阵
    [编程题] N阶楼梯上楼问题
    2017年东北大学计算机专业考博 面试编程题(某教授 实验室)
    幸运的袋子 (牛客网 16年网易内推 编程题)
    OpenvSwitch代码分析之bridge和port
    阅读书籍---程序员必读系列
    嵌入式开发之davinci--- 8168 电源调试总结
    嵌入式开发之davinci--- 8148/8168/8127 中的添加算饭scd 场景检测 文档简介
    嵌入式开发之davinci--- 8148/8168/8127 中的图像缩放sclr、swms之后出现图像视频卡顿、屏幕跳跃的问题
  • 原文地址:https://www.cnblogs.com/wls001/p/8696940.html
Copyright © 2011-2022 走看看