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 ...
随机推荐
- 设计模式系列之过滤器模式(Chriteria Pattern)
过滤器模式(Filter Pattern)或标准模式(Criteria Pattern)是一种设计模式,这种模式允许开发人员使用不同的标准来过滤一组对象,通过逻辑运算以解耦的方式把它们连接起来.这种类 ...
- JavaScript中的闭包和作用域链
这部分几乎是JavaScript中最难的部分,也是面试官最爱问的地方. 下面的内容是我以前写的<JavaScript学习手册>中被客户删除的部分,理由听起来有点诡异:太难.
- ORACLE中关于表的一些特殊查询语句
1: 如何判断字段的值里面:那些数据包含小写字母或大小字母 判断字段NAME的值里面有小写字母的记录 方式1: SELECT NAME FROM TEST WHERE regexp_like(NAME ...
- Python变量之白首如新,倾盖如故
python中的变量变量:将运算的中间结果暂存到内存中,方便后续程序调用.变量的命名规则:1.变量名由字母.数字.下划线组成.2.变量名可以用字母.下划线开头,但是不能以数字开头.3.变量名是区分大小 ...
- Java 集合系列(一)
Java集合系列文章将以思维导图为主要形式来展示知识点,让零碎的知识形成体系. 这篇文章主要介绍的是[Java 集合的基本知识],即Java 集合简介. 毕业出来一直使用 PHP 进行开发,对于大学所 ...
- Saltstack_使用指南02_远程执行-验证
1. 主机规划 2. Master与哪些minion通信 2.1. Master与哪些minion正常通信 [root@salt100 ~]# salt '*' test.ping salt100: ...
- Python开发【第四篇】函数
函数的作用 函数可以让编程逻辑结构化以及模块化 无论是C.C++,Java还是Python,函数是必不可少的知识点,也是很重要的知识点,函数是完成一个功能的代码块,使用函数可以使逻辑结构变得更加清晰以 ...
- kernel笔记——内核编译与进程管理
内核与操作系统 由于一些商业操作系统设计上的缺陷以及日益庞杂,“操作系统”的概念对很多人而言变得含糊不清.在进一步讨论Linux内核的话题前,我们先区分“内核”与“操作系统”这两个概念. 操作系统:指 ...
- vue给不同环境配置不同打包命令
第1步:安装cross-env 1 npm i --save-dev cross-env 第2步:修改各环境下的参数 在config/目录下添加test.env.js.pre.env.js. 修改pr ...
- [APIO2014]序列分割
嘟嘟嘟 复习一下斜率优化,感觉已经忘得差不多了-- 这题切入点在与答案跟切的顺序无关. 证明就是假如有三段权值分别为\(x, y, z\),那么这两刀不管按什么顺序切,得到的结果都是\(xy + xz ...