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 ...
随机推荐
- Python使用Plotly绘图工具,绘制气泡图
今天来讲讲如何使用Python 绘图工具,Plotly来绘制气泡图. 气泡图的实现方法类似散点图的实现.修改散点图中点的大小,就变成气泡图. 实现代码如下: import plotly as py i ...
- Python第四天 流程控制 if else条件判断 for循环 while循环
Python第四天 流程控制 if else条件判断 for循环 while循环 目录 Pycharm使用技巧(转载) Python第一天 安装 shell 文件 Python第二天 ...
- Django 数据流程图
根据学习Django并且通过几个作业,发现Django制作网站的数据流程有些比较难懂,所以制作一个数据流程图,帮助自己理解,也希望对正学习的人有所帮助! 别的不多说,上美图:
- Docker资源限制
我们在容器中运行docker镜像的时候,可以指定一些设置容器cpu和内存的相关参数来进行限制,这样子尽量把容器资源做的相对稳定一些.这些参数是在docker run/create命令使用,比如: -- ...
- jest 自动化测试
概述 jest 是 facebook 开源的,用来进行单元测试的框架,可以测试 javascipt 和 react. 单元测试各种好处已经被说烂了,这里就不多扯了.重点要说的是,使用 jest, 可以 ...
- 我的第一个python web开发框架(28)——定制ORM(四)
在数据库操作时,新增记录也是必不可少的,接下来我们应用字典的特性来组合sql语句 先上产品新增接口代码 @post('/api/product/') def callback(): "&qu ...
- web框架开发-Django模型层(1)之ORM简介和单表操作
ORM简介 不需要使用pymysql的硬编码方式,在py文件中写sql语句,提供更简便,更上层的接口,数据迁移方便(有转换的引擎,方便迁移到不同的数据库平台)…(很多优点),缺点,因为多了转换环节,效 ...
- vim之快速查找功能
vim有强大的字符串查找功能. 我们通常在vim下要查找字符串的时候, 都是输入 / 或者 ? 加 需要查找的字符串来进行搜索,比如想搜索 super 这个单词, 可以输入 /super 或者 ...
- KEIL_MDK生成Bin文件
1.MDK配置 MDK是使用安装目录下的(formelf.exe)工具来生成bin文件,配置方法:勾选 "Run # 1",在后面输入框写入bin文件生成方式 2.绝对路径 &qu ...
- Golang 入门系列(五)GO语言中的面向对象
前面讲了很多Go 语言的基础知识,包括go环境的安装,go语言的语法等,感兴趣的朋友可以先看看之前的文章.https://www.cnblogs.com/zhangweizhong/category/ ...