码迷,mamicode.com
首页 > 其他好文 > 详细

[SCOI2010]幸运数字

时间:2018-02-21 20:47:27      阅读:168      评论:0      收藏:0      [点我收藏+]

标签:double   space   根据   map   pre   解题思路   iostream   reg   post   

题目背景

四川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

解题思路:

(暴力都没写对,还是细心的问题。)

观察可知,可以预处理出所有的幸运数字,不超过5000个

然后枚举对应范围内的合法数字,但是发现会有重复。怎们办呢?

对于某个幸运数字,如果他是另一个幸运数字的倍数,就删去他(因为枚举另一个幸运数字的倍数时一定会枚举到他)。

对于剩下的大约n==2000个幸运数字,搜索得到答案。

从n个数字中选取y个数字,最小公倍数为z,那么贡献为r/z-(l-1)/z;

但是依然会有重复,根据容斥原理(仔细想想):

就--> +1个的-2个的+3个的-4个的.......

(详见代码)

#include<iostream>
#include<cstdio>
#include<map>
#include<algorithm>
#define ll long long
using namespace std;
inline ll read()
{
    ll x=0,w=1;char ch=getchar();
    while(!isdigit(ch)){if(ch==-) w=-1;ch=getchar();}
    while(isdigit(ch)) x=(x<<3)+(x<<1)+ch-0,ch=getchar();
    return x*w;
}
ll x,y,a[5000],k,ans,s[5000],p;
bool fg[5000];
bool cmp(ll x,ll y){return x>y;}
void dfs(int x,ll nw)
{
    if(x==12) return;
    a[++k]=nw*10+6;
    dfs(x+1,a[k]);
    a[++k]=nw*10+8;
    dfs(x+1,a[k]);
}
ll gcd(ll x,ll y)
{
    ll r=x%y;
    while(r) x=y,y=r,r=x%y;
    return y;
}
void DFS(int nw,int u,ll z)
{
    if(nw>p)
    {
        if(u&1) ans+=y/z-(x-1)/z;
        else if(u) ans-=y/z-(x-1)/z;
        return;
    }
    DFS(nw+1,u,z);;
    ll tmp=z/gcd(s[nw],z);
    if((double)tmp*s[nw]<=y) DFS(nw+1,u+1,tmp*s[nw]);
}
int main()
{
    dfs(1,0);
    for(int i=1;i<=k;++i)
     for(int j=1;j<=k;++j)
      if(j!=i && a[i]%a[j]==0)
      {fg[i]=1;break;}
    for(int i=1;i<=k;++i)
     if(!fg[i]) s[++p]=a[i];
    sort(s+1,s+p+1,cmp);
    x=read();y=read();
    DFS(1,0,1);
    printf("%lld",ans);
    return 0;
}

交友须带三分侠气,作人要存一点素心 。

 

[SCOI2010]幸运数字

标签:double   space   根据   map   pre   解题思路   iostream   reg   post   

原文地址:https://www.cnblogs.com/adelalove/p/8457096.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!