CF55D Beautiful numbers
题意
定义一个数字\(x\)是\(beautiful\ number\)当且仅当\(x\)可以被其十进制表示下所有非\(0\)位置的数整除。
例如\(24\)是一个\(beautiful\ number\),因为他可以被\(2\)和\(4\)整除。
而\(28\)不是一个\(beautiful\ number\),因为他不能被\(8\)整除
给出两个数字\(L,R\; (1 \le L\le R \le 10^{18})\)
求出区间\([L,R]\)内有多少\(beautiful\ number\)
思路
首先显然的数位\(dp\)
先不考虑空间和时间问题
要让一个数字\(x\)整除所有数位上的数字。其实也就是要整除这些数字的最小公倍数\((lcm)\)。
用\(f[i][j][k]\)表示当前到了第\(i\)位,当前数字为\(j\;\) (先不管能否空间是否足够)。所选数字的\(lcm\)为\(k\)的方案数。
搜到最后看一下\(lcm\)是否整除\(j\)即可。
然后考虑空间问题。
在\(f[i][j][k]\)中,\(i\)是\(18\)左右,\(j\)是\(10^{18}\),\(k\)最大是\(2520\)(\(2520\)是\(1\) ~ \(9\)的\(lcm\))
考虑优化一下\(j\)这一维。
显然所有可能的\(lcm\)都是\(2520\)的因数。
而比较显然的
\]
所以我们可以把\(j\)那一维的数以\(2520\)为模数\(hash\)一下。
然后优化\(k\)那一维。
枚举一下可以发现。\(1\)~\(9\)的所有可能组合中。\(lcm\)的种类其实只有\(50\)种左右。所以就可以把最后一维压成\(50\)左右
然后就可以愉快的数位\(dp\)啦!
代码
/*
* @Author: wxyww
* @Date: 2019-03-17 08:30:41
* @Last Modified time: 2019-03-17 19:36:46
*/
#include<cstdio>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<queue>
#include<vector>
#include<ctime>
using namespace std;
typedef long long ll;
const int LCM = 2520;
#define int ll
ll read() {
ll x = 0, f = 1; char c = getchar();
while (c < '0' || c > '9') {
if (c == '-') f = -1;
c = getchar();
}
while (c >= '0' && c <= '9') {
x = x * 10 + c - '0';
c = getchar();
}
return x * f;
}
ll L, R;
int dy[100], pk[LCM + 100];
int get_lcm(int x, int y) {
if (!y) return x;
return x * y / __gcd(x, y);
}
namespace BF2 {
int pos, f[20][3000][60], a[20];
ll dp(ll p, ll now, ll lcm, int lim) {
if (!p) return now % dy[lcm] == 0;
if (f[p][now][lcm] != -1 && !lim) return f[p][now][lcm];
int up = 9;
if (lim) up = a[p];
int tmp = 0;
for (int i = 0; i <= up; ++i)
tmp += dp(p - 1, ((now * 10 + i) % LCM), pk[get_lcm(dy[lcm], i)], lim & i == up);
if (!lim) f[p][now][lcm] = tmp;
return tmp;
}
ll solve(ll x) {
pos = 0;
while (x) {
a[++pos] = x % 10; x /= 10;
}
return dp(pos, 0, 1, 1);
}
void main() {
cout << solve(R) - solve(L - 1) << endl;
}
}
signed main() {
int T = read();
memset(BF2::f, -1, sizeof(BF2::f));
int cnt = 0;
for (int i = 1; i <= LCM; ++i) {
if (LCM % i == 0) {
dy[++cnt] = i; pk[i] = cnt;
}
}
while (T--) {
L = read(), R = read();
BF2::main();
}
return 0;
}
CF55D Beautiful numbers的更多相关文章
- 洛谷 CF55D Beautiful numbers 解题报告
CF55D Beautiful numbers 题意 \(t(\le 10)\)次询问区间\([l,r](1\le l\le r\le 9\times 10^{18})\)中能被每一位上数整除的数的个 ...
- [暑假集训--数位dp]cf55D Beautiful numbers
Volodya is an odd boy and his taste is strange as well. It seems to him that a positive integer numb ...
- CF55D Beautiful numbers 题解
题目 Volodya is an odd boy and his taste is strange as well. It seems to him that a positive integer n ...
- cf55D. Beautiful numbers(数位dp)
题意 题目链接 Sol 看到这种题就不难想到是数位dp了. 一个很显然的性质是一个数若能整除所有位数上的数,则一定能整除他们的lcm. 根据这个条件我们不难看出我们只需要记录每个数对所有数的lcm(也 ...
- CF55D Beautiful numbers (数位dp)
题目链接 题解 一个数能被一些数整除,那么一定被这些数的\(lcm\)整除 那么我们容易想到根据\(lcm\)设状态 我们可以发现有用的\(lcm\)只有\(48\)个 那么按照一般的数位\(dp\) ...
- 【数位DP】CF55D Beautiful numbers
$dp[x][p][pp]$表示第x位,当前已有数字mod 2520(1~9数字的lcm)为p,当前各位数字的lcm为pp 观察到数组太大,考虑压缩,第三维lcm最多只有9个数字,打表发现最多只有48 ...
- 【CF55D】Beautiful numbers(动态规划)
[CF55D]Beautiful numbers(动态规划) 题面 洛谷 CF 题解 数位\(dp\) 如果当前数能够被它所有数位整除,意味着它能够被所有数位的\(lcm\)整除. 所以\(dp\)的 ...
- 【CF55D】Beautiful numbers
[CF55D]Beautiful numbers 题面 洛谷 题解 考虑到如果一个数整除所有数那么可以整除他们的\(lcm\),而如果数\(x\)满足\(x\bmod Lcm(1,2...,9)=r\ ...
- CodeForces 55D Beautiful numbers
D. Beautiful numbers time limit per test 4 seconds memory limit per test 256 megabytes input standar ...
随机推荐
- C++ 浅拷贝与深拷贝探究
C++浅拷贝与深拷贝探究 浅拷贝与深拷贝的概念是在类的复制/拷贝构造函数中出现的. 拷贝构造函数使用场景 对象作为参数,以值传递方式传入函数(要调用拷贝构造函数将实参拷贝给函数栈中的形参) 对象作为返 ...
- angular应用容器化部署
angular 应用容器化部署 Intro 我自己有做一个个人主页,虽然效果不怎么样(不懂设计的典型程序猿...),但是记录了我对于前端框架及工具的一些实践, 从开始只有一个 angularjs 制作 ...
- Android PAI (PlayAutoInstall)预装APK 功能
最近刚找到工作,是手机方案公司,刚接触手机系统预装的APP,以及解决方案MTK平台下预装APP的bug,也接触到了Launcher的东西. 然后接触到了第一个需求 PAI预装APK功能 下面是我用到的 ...
- C# 一般处理程序ashx接收服务端post过来json数据
这个和前端js的接收方式有点不一样,前端接收用request.form["xxx"]即可
- python3 dict(字典)
clear(清空字典内容) stu = { 'num1':'Tom', 'num2':'Lucy', 'num3':'Sam', } print(stu.clear()) #输出:None copy( ...
- MFC桌面电子时钟的设计与实现
目录 核心技术 需求分析 程序设计 程序展示 (一)核心技术 MFC(Micosoft Foundation Class Libay,微基础类库)是微基于Windows平台下的C++类库集合,MFC包 ...
- const int *p;int *const p;区别及用法
在单片机程序设计中,我们经常会用到const这个关键字,在有些单片机的编译器中可能会是code(比如51系列单片机),但我们在学习C语言的时候,首先还是先学到的const.我们知道,const关键字的 ...
- 英语进阶系列-A06-本周总结
本周总结 目录Content 英语进阶系列-A01-再别康桥 英语进阶系列-A02-英语学习的奥秘 英语进阶系列-A03-英语升级练习一 英语进阶系列-A04-英语升级练习二 英语进阶系列-A05-英 ...
- Linux下配置nfs并远程挂载实战探讨
简单介绍: nfs是网络文件系统,允许一个节点通过网络访问远程计算机的文件系统,远程文件系统可以被直接挂载到本地,文件操作和本地没有区别,如果是局域网的nfs那么io的性能也可以保证 nfs是Netw ...
- 2019年桌面Linux需要做好的7件事
2019年桌面Linux需要做好的7件事 新的一年已经到来,这意味着又一年过去了,Linux还是没有发现自己主宰了桌面.Linux在许多方面做得非常好,在接下来的几周,我们将研究一些最适合您各种需求的 ...