[洛谷P2567] SCOI2010 幸运数字
问题描述
在中国,很多人都把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 10
样例输出
2
数据范围
对于30%的数据,保证1<=a<=b<=1000000
对于100%的数据,保证1<=a<=b<=10000000000
出处
四川省选2010
题目大意
定义集合\(S\)为包含所有\([1,10^{10}]\)中仅由6和8构成的数字的倍数集合。求区\([l,r]\)中属于\(S\)的元素个数。
解析
First of all
想到用类似于数位DP的方法,对每一位枚举选择哪个数,然后对每个构造出来的在区间\([l,r]\)数验证是否是一个幸运数字的倍数。显然,这种做法的复杂度极其之高,我们可以换一种思路。
另一个思路
既然难以验证一个数是不是幸运数字的倍数,那么我们反过来,提前构造出所有幸运数字(具体可用搜索实现),然后枚举他们的倍数,统计有多少个是在\([l,r]\)中,得到答案。
如何统计呢?
引理
对于一个数\(x\),它在区间\([l,r]\)的倍数个数为
\[\left \lfloor \frac{r}{x} \right \rfloor - \left \lceil \frac{l}{x} \right \rceil+1
\]
所以,是不是对每一个幸运数字代入公式计算一下,累加答案就可以了呢?
容斥
答案是否定的。
一个很简单的道理,48是6和8的倍数,所以它会同时被6和8计算,也就是说,48被重复统计了一次。总结一下,任意几个幸运数字的\(lcm\)都会被重复统计。
拓展:\(lcm\)
\(lcm(a,b)\)指的是\(a\)和\(b\)的最小公倍数。计算公式为\(lcm(a,b)=a*b/gcd(a,b)\)
如果gcd也不知道就自行百度吧。
既然会重复统计\(lcm\),我们就减掉一份两两最小公倍数带来的贡献。但是这样又会重复减掉任意三个数的最小公倍数的贡献,那么我们再加回来,又多加了任意四个数最小公倍数的贡献......。公式化之后就是
\]
其中\(f(x)=\left \lfloor \frac{r}{x} \right \rfloor - \left \lceil \frac{l}{x} \right \rceil+1\),\(a[i]\)为第i个幸运数字。
搜索
有了容斥式,我们来考虑如何计算。用DFS可以很方便的解决。每次枚举一个数是否被选,最后如果选的数个数为奇数就加上\(f(lcm)\),否则减掉。
但这样还是不能通过。
剪枝
- 考虑类似于6和66的关系,66是6的倍数,那么66的倍数也都会被6计算到。所以,我们可以删去所有是其他幸运数字倍数的幸运数字。
- 如果当前\(lcm\)已经大于\(r\),那么显然没有什么枚举下去的必要了。这时就可以剪枝。
- 可以把所有剩下的幸运数字从大到小排序后再DFS。这样在前几个阶段中就删去了很多\(lcm\)大于\(r\)的情况。
一个小问题
即便如此,这道题提交时还是会T几个点。原因是在计算DFS过程中计算\(lcm\)时\(long\ \ long\)溢出了。因此,我们需要使用\(long \ \ double\)类型计算避免此问题。
代码
#include <iostream>
#include <cstdio>
#include <algorithm>
#define int long long
using namespace std;
const int lim=10000000000;
int i,j,l,r,num[1000002],cnt,n,ans;
bool vis[1000002];
void make(int x,int now)
{
if(now>lim) return;
if(now!=0) num[++cnt]=now;
make(x+1,now*10+6);
make(x+1,now*10+8);
}
int gcd(int a,int b)
{
if(b==0) return a;
return gcd(b,a%b);
}
void dfs(int x,int cnt,int lcm)
{
if(x==n+1){
if(lcm!=1) ans+=(cnt%2==0?-1:1)*(r/lcm-(l/lcm+(l%lcm==0?0:1))+1);
return;
}
dfs(x+1,cnt,lcm);
long double tmp=1.0*lcm/gcd(lcm,num[x])*num[x];
if(tmp>r) return;
dfs(x+1,cnt+1,tmp);
}
int my_comp(const int &x,const int &y)
{
return x>y;
}
signed main()
{
cin>>l>>r;
make(0,0);
sort(num+1,num+cnt+1);
for(i=1;i<=cnt;i++){
for(j=i+1;j<=cnt;j++){
if(num[j]%num[i]==0) vis[j]=1;
}
}
for(i=1;i<=cnt;i++){
if(!vis[i]) num[++n]=num[i];
}
sort(num+1,num+n+1,my_comp);
dfs(1,0,1);
printf("%lld\n",ans);
return 0;
}
[洛谷P2567] SCOI2010 幸运数字的更多相关文章
- P2567 [SCOI2010]幸运数字 DFS+容斥定理
P2567 [SCOI2010]幸运数字 题目描述 在中国,很多人都把6和8视为是幸运数字!lxhgww也这样认为,于是他定义自己的“幸运号码”是十进制表示中只包含数字6和8的那些号码,比如68,66 ...
- P2567 [SCOI2010]幸运数字
题目 P2567 [SCOI2010]幸运数字 做法 容斥+剪枝 先预处理幸运数字,别看数据范围这么大,其实也没几个,然后去掉倍数这种 然后处理相似数字,一眼的容斥,递归选数然后求出这些的公倍数容斥一 ...
- [洛谷P3292] [SCOI2016]幸运数字
洛谷题目链接:[SCOI2016]幸运数字 题目描述 A 国共有 n 座城市,这些城市由 n-1 条道路相连,使得任意两座城市可以互达,且路径唯一.每座城市都有一个幸运数字,以纪念碑的形式矗立在这座城 ...
- 洛谷P3292 [SCOI2016] 幸运数字 [线性基,倍增]
题目传送门 幸运数字 题目描述 A 国共有 n 座城市,这些城市由 n-1 条道路相连,使得任意两座城市可以互达,且路径唯一.每座城市都有一个幸运数字,以纪念碑的形式矗立在这座城市的正中心,作为城市的 ...
- Luogu P2567 [SCOI2010]幸运数字 容斥+脑子
双倍经验:BZOJ 2393 Cirno的完美算数教室 做法:先把$[1,r]$中所有的幸运数字筛出来,然后用这些幸运数字来筛$[l,r]$中的近似幸运号码: 剪枝:当一个幸运数字$a[i]$是另一个 ...
- 洛谷P3292 [SCOI2016]幸运数字 线性基+倍增
P3292 [SCOI2016]幸运数字 传送门 题目描述 A 国共有 n 座城市,这些城市由 n-1 条道路相连,使得任意两座城市可以互达,且路径唯一.每座城市都有一个幸运数字,以纪念碑的形式矗立在 ...
- 洛谷P3292 [SCOI2016]幸运数字(倍增+线性基)
传送门 不知道线性基是什么东西的可以看看蒟蒻的总结 第一眼:这不会是个倍增LCA暴力合并线性基吧…… 打了一发……A了? 所以这真的是个暴力倍增LCA合并线性基么…… ps:据某大佬说其实可以离线之后 ...
- 【LG2567】[SCOI2010]幸运数字
[LG2567][SCOI2010]幸运数字 题面 洛谷 题目大意: 问你区间\([L,R](1\leq L\leq R\leq 10^{10})\)中有几个数是仅由\(6,8\)组成的数的倍数. 题 ...
- BZOJ 1853: [Scoi2010]幸运数字
1853: [Scoi2010]幸运数字 Time Limit: 2 Sec Memory Limit: 64 MBSubmit: 2117 Solved: 779[Submit][Status] ...
随机推荐
- hibernate中get和load区别
在日常开发中,获取数据时必不可少的,这样就要用到get和load方法来实现了.下面简单说一下get和load的区别. 1.返回值不同 使用get方法检索数据时,没有该数据返回值为null. 而使用lo ...
- C 语言的函数 - 内存分析
函数基本概念 Linux 中,函数在内存的代码段(code 区),地址比较靠前. 函数定义 C 语言中,函数有三个要素:入参.返回值.函数名,缺一不可.函数使用前必须先声明,或者在使用之前定义. 函数 ...
- 那些堪称神器的 Chrome 插件
Chrome 的简洁快速以及丰富的插件种类使得它在国内日益盛行,帮助了我们很多 Chrome 用户提升了工作效率,而今天要给大家推荐8款实用甚至堪称神器的 Chrome 插件,希望对提升大家的工作效率 ...
- aiXcoder安装&使用
1.官网下载 https://www.aixcoder.com/#/setting 1.1介绍 1.2选择对应的下载版本 1.3安装&注册(需关闭IDEA) 安装完进行手机/邮箱注册,下载对应 ...
- debian下安装mysql 5.1.34
#cd /usr/local/src # tar xvzf mysql-5.1.34.tar.gz # cd mysql-5.5.1.34 配置和编译 #chmod +x configure # ./ ...
- 十、Zabbix-自动关联模板
之前的文章中,我们实现了自动注册,自动分组:并且创建了模板,监控项,触发器.为的就是能够实现主机自动被期望的监控项监控到.接下来我们只要能让自动注册的主机能够自动连接到我们设置好的模板,就可以实现自动 ...
- SpringBoot 使用 RestTemplate 调用exchange方法 显示错误信息
SpringBoot使用RestTempate SpringBoot使用RestTemplate摘要认证 SpringBoot使用RestTemplate基础认证 SpringBoot使用RestTe ...
- Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/commons/cli2/Option
今天,在做canopy算法实例时,遇到这个问题,所以记录下来.下面是源码: package czx.com.mahout; import java.io.IOException; import org ...
- Zend_Cache的使用
一.Zend_Cache快速浏览 Zend_Cache 提供了一个缓存任何数据的一般方法. 在Zend Framework中缓存由前端操作,同时通过后端适配器(File, Sqlite, Memcac ...
- java虚拟机学习总结之GC回收算法与GC收集器
GC回收算法 1.标记清除算法分为标记阶段和清除阶段标记阶段:通过特定的判断方式找出无用的对象实例并将其标记清除阶段:将已标记的对象所占用的内存回收缺点:运行多次以后容易产生空间碎片,当需要一整段连续 ...