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 ...
随机推荐
- location.origin不兼容IE8解决方案
最近项目中遇到一个问题,在ajax跟后台交互时需要传一个全路径url.项目上线后,在谷歌,火狐,360等浏览器访问一切正常.但唯独IE8下出现问题,提示url:undefined ! 这就尴尬了!!! ...
- SQL Server数据库————连接查询和分组查询
SQL Server数据库————连接查询和分组查询 分组查询 select 列from <表名> where …… group by 列 注意:跟order by一样group ...
- Linux 文件权限管理
1.文件权限的概述 在Linux系统下,使用权限来保护资源的安全将是一种不错的选择.系统中每个文件的权限都有可读(r).可写(w)和可执行(x)这三种权限,它们分别对应权限数值4.2 和1.系统为每个 ...
- IIS 反向代理到 Apache、Tomcat
将请求的网址重写重定向到其它网址.当80端口被占用无法同时使用两个Web服务的解决方案,使得IIS和Apache Tomcat 共存 环境 WindowServer 2008 IIS7 Apache ...
- java类加载及类初始化
1.前言 java是跨平台语言,主要是因为它的java虚拟机的存在,java有事编译语言,所以需要将编写的java文件编译成jvm可运用的class字节码文件.在java中一切皆对象.对于Java虚拟 ...
- 谈谈当代大学生学习IT技术的必要性。
21世纪,人类社会已经从工业时代全面进入信息化时代,IT技术的发展正在影响人类的日常生活.比如,外卖平台给人们的用餐提供了更多的选择,移动支付颠覆了传统的支付方式.网购使得人们的购物更加方便,真正做到 ...
- Benchmarking Apache Kafka: 2 Million Writes Per Second (On Three Cheap Machines)
I wrote a blog post about how LinkedIn uses Apache Kafka as a central publish-subscribe log for inte ...
- SQL NULL 函数
SQL ISNULL().NVL().IFNULL() 和 COALESCE() 函数 请看下面的 "Products" 表: P_Id ProductName UnitPrice ...
- day4-python基础-小数据池以及深浅copy浅讲
今天的目录是 1.小数据池 2.深浅copy 正文开始 1.小数据池 在说明今天的内容前,先说明一个在今天重复用到的一个知识点 ###比较’=’俩边的数据是否完全相同,以及判断一个对象的内存地址是否完 ...
- Centos7.x做开机启动脚本
cat /etc/centos-release CentOS Linux release 7.4.1708 (Core) uname -r 3.10.0-693.11.1.el7.x86_64 vim ...