题意:求闭区间内能被6和8组成的数字整除的数目。n<=1e11.

我们可以预处理出这些6和8组成的数字,大概2500个,然后排除一些如88,66的情况。这样大概还剩下1000个。

转化为[0,r]和[0,l-1]的问题,显然需要运用容斥原理。ans=n/6+n/8+n/68+...+...-n/lcm(6,8)-n/lcm(6,68)......

因此用dfs即可计算出来,这样一看复杂度好像是2^1000的样子,但是注意到lcm增长的很快,如果lcm>n那么显然之后的这些情况就可以忽略了。

这就是一个强有力的剪枝。

另外从大到小dfs要比从小到大dfs要好。大概常数小?

# include <cstdio>
# include <cstring>
# include <cstdlib>
# include <iostream>
# include <vector>
# include <queue>
# include <stack>
# include <map>
# include <set>
# include <cmath>
# include <algorithm>
using namespace std;
# define lowbit(x) ((x)&(-x))
# define pi acos(-1.0)
# define eps 1e-
# define MOD
# define INF
# define mem(a,b) memset(a,b,sizeof(a))
# define FOR(i,a,n) for(int i=a; i<=n; ++i)
# define FO(i,a,n) for(int i=a; i<n; ++i)
# define bug puts("H");
# define lch p<<,l,mid
# define rch p<<|,mid+,r
# define mp make_pair
# define pb push_back
typedef pair<int,int> PII;
typedef vector<int> VI;
# pragma comment(linker, "/STACK:1024000000,1024000000")
typedef long long LL;
int Scan() {
int x=,f=;char ch=getchar();
while(ch<''||ch>''){if(ch=='-')f=-;ch=getchar();}
while(ch>=''&&ch<=''){x=x*+ch-'';ch=getchar();}
return x*f;
}
void Out(int a) {
if(a<) {putchar('-'); a=-a;}
if(a>=) Out(a/);
putchar(a%+'');
}
const int N=;
//Code begin... LL num[], pos1, pos2, p[], mark[];
void init(){
p[]=; FOR(i,,) p[i]=p[i-]*;
int l=, r=, tmpl, tmpr;
num[++pos1]=; num[++pos1]=;
FOR(i,,) {
tmpl=r+;
FOR(j,l,r) num[++pos1]=*p[i-]+num[j];
FOR(j,l,r) num[++pos1]=*p[i-]+num[j];
tmpr=pos1;
l=tmpl; r=tmpr;
}
FOR(i,,pos1) {
int flag=true;
FO(j,,i) if (num[i]%num[j]==) {flag=false; break;}
if (flag) mark[++pos2]=num[i];
}
mark[++pos2]=1e16;
}
LL dfs(int pos, int flag, LL x, LL cheng){
if (pos<=) return ;
LL res=;
res+=dfs(pos-,flag,x,cheng);
LL tmp=__gcd(cheng,mark[pos]);
if (cheng/tmp<=(double)x/mark[pos]) {
LL tt=cheng/tmp*mark[pos];
res+=dfs(pos-,flag^,x,tt);
res+=(flag?x/tt:-x/tt);
}
return res;
}
LL sol(LL x){
for (int i=pos2; i>=; --i) if (mark[i]<=x) return dfs(i,,x,);
return ;
}
int main ()
{
init();
LL a, b;
scanf("%lld%lld",&a,&b);
printf("%lld\n",sol(b)-sol(a-));
return ;
}

BZOJ 1853 幸运数字(容斥原理+dfs)的更多相关文章

  1. [SCOI2010]幸运数字 [容斥原理 dfs]

    题意:"幸运号码"是十进制表示中只包含数字6和8的那些号码,求\([l,r]:r \le 10^10\)之间"幸运号码"的倍数个数 发现幸运号码貌似很少唉,去掉 ...

  2. BZOJ 1853 幸运数字

    需要优化一波常数. 以及刚才那个版本是错的. #include<iostream> #include<cstdio> #include<cstring> #incl ...

  3. Bzoj 1853: [Scoi2010]幸运数字 容斥原理,深搜

    1853: [Scoi2010]幸运数字 Time Limit: 2 Sec  Memory Limit: 64 MBSubmit: 1774  Solved: 644[Submit][Status] ...

  4. 1853: [Scoi2010]幸运数字[容斥原理]

    1853: [Scoi2010]幸运数字 Time Limit: 2 Sec  Memory Limit: 64 MBSubmit: 2405  Solved: 887[Submit][Status] ...

  5. BZOJ 4568 幸运数字

    题目传送门 4568: [Scoi2016]幸运数字 Time Limit: 60 Sec Memory Limit: 256 MB Description A 国共有 n 座城市,这些城市由 n-1 ...

  6. BZOJ1853 [Scoi2010]幸运数字 容斥原理

    欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ1853 题意概括 求一个区间范围内,近似幸运数字的个数. 定义: 幸运数字:仅由6或者8组成的数字. ...

  7. 【BZOJ1853】[Scoi2010]幸运数字 容斥原理+搜索

    Description 在中国,很多人都把6和8视为是幸运数字!lxhgww也这样认为,于是他定义自己的"幸运号码"是十进制表示中只包含数字6和8的那些号码,比如68,666,88 ...

  8. [luogu2576 SCOI2010] 幸运数字 (容斥原理)

    传送门 Description 在中国,很多人都把6和8视为是幸运数字!lxhgww也这样认为,于是他定义自己的"幸运号码"是十进制表示中只包含数字6和8的那些号码,比如68,66 ...

  9. bzoj1853幸运数字——容斥原理

    题目:http://www.lydsy.com/JudgeOnline/problem.php?id=1853 dfs实现容斥原理即可. 注意:若在init中写“cnt++”,则出来后需要先cnt-- ...

随机推荐

  1. 20155330 实验一《Java开发环境的熟悉》(Windows+IDEA)实验报告

    实验知识点 JVM.JRE.JDK的安装位置与区别: 命令行运行javac:java:javac -cp; java -cp: PATH,CLASSPATH,SOURCEPATH的设定方法与应用: 包 ...

  2. [BZOJ2961]共点圆-[凸包+cdq分治]

    Description 传送门 Solution 考虑对于每一个点: 设圆的坐标为(x,y),点的坐标为(x0,y0).依题意得,当一个点在圆里,需要满足(x-x0)2+(y-y0)2<=x2+ ...

  3. SaltStack入门篇(四)之深入理解SaltStack远程执行

    1.目标 2.执行模块 3.返回 salt ‘*’ cmd.run ‘uptime’ 命令 目标 执行模块 执行模块参数 1.SlatStack远程执行–目标 执行目标:https://docs.sa ...

  4. thinkphp5 开启多语言

    一.配置点击打开链接1.开启语言包功能'lang_switch_on' => true,2.支持的语言列表'lang_list' => ['zh-cn','en-us'],二.语言定义(默 ...

  5. centos7下python3与python2共存并且开启py3虚拟环境

    因为下载视频需要用到python3环境,今天在我的win上安装下载工具死活安装不上去,在大盘鸡上一下就安装成功了...可能在win上不兼容吧...无奈只能在大盘鸡上进行折腾了,顺便几个笔记 由于大盘鸡 ...

  6. java阻塞队列之ArrayBlockingQueue

    在Java的java.util.concurrent包中定义了和多线程并发相关的操作,有许多好用的工具类,今天就来看下阻塞队列.阻塞队列很好的解决了多线程中数据的安全传输问题,其中最典型的例子就是客园 ...

  7. ubuntn 安装软件

    安装输入法 一.Ctrl+Alt+T打开终端,输入sudo apt-get install fcitx,安装fcitx插件. 二.打开input method,选择fcitx. 三.打开system ...

  8. linux部署MantisBT(一)部署apache

    一.部署apache 1.下载apache安装包及依赖包 http://httpd.apache.org/download.cgi#apache24(apache2)http://apr.apache ...

  9. TPO 02 - Desert Formation

    TPO 02 - Desert Formation NOTE: 主要意思(大概就是主谓宾)用粗体标出:重要的其它用斜体: []中的是大致意思,可能与原文有关也可能无关,但不会离题 目的为训练句子/段落 ...

  10. 优化 VR 动作类游戏《Space Pirate Trainer*》以便在英特尔® 集成显卡上实现卓越的表现

    Space Pirate Trainer* 是一款面向 HTC Vive*.Oculus Touch* 和 Windows Mixed Reality* 的原创发行游戏.版本 1.0 于 2017 年 ...