Codeforces 55D Beautiful Number (数位统计)
把数位dp写成记忆化搜索的形式,方法很赞,代码量少了很多。
下面为转载内容:
a positive integer number is beautiful if and only if it is divisible by each of its nonzero digits.
问一个区间内[l,r]有多少个Beautiful数字
范围9*10^18
数位统计问题,构造状态也挺难的,我想不出,我的思维局限在用递推去初始化状态,而这里的状态定义也比较难
跟pre的具体数字有关
问了NotOnlySuccess的,豁然开朗 Orz
一个数字要被它的所有非零位整除,即被他们的LCM整除,可以存已有数字的Mask,但更好的方法是存它们的LCM{digit[i]}
int MOD = LCM{1,2,
9} = 5 * 7 * 8 * 9 = 2520
按照定义,数字x为Beautiful :
x % LCM{digit[xi]} = 0
即 x % MOD % LCM{digit[xi]} = 0
所以可以只需存x % MOD,范围缩小了
而在逐位统计时,假设到了pre***(pre指前面的一段已知的数字,而*是任意变)
( preSum * 10^pos + next ) % MOD % LCM(preLcm , nextLcm)
= ( preSum * 10 ^ pos % MOD + next % MOD ) % LCM(preLcm , nextLcm)
== 0
而next,nextLcm是变量,上面的比较式的意义就是
在已知pos , preSum , preLcm情况下有多少种(next,nextLcm)满足式子为0
而这个就是一个重复子问题所在的地方了,需要记录下来,用记忆化搜索
dfs(pos , preSum , preLcm , doing)
加一个标记为doing表示目前是在计算给定数字的上限,还是没有上限,即***类型的
这样就将初始化以及逐位统计写在一个dfs了,好神奇!!!
还有一点,10以内的数字情况为2^3 , 3^2 , 5 , 7
所以最小公倍数组合的情况只有4*3*2*2 = 48
可以存起来,我看NotOnlySuccess的写法是
for(int i = 1 ; i <= MOD ; i ++)
{
if(MOD % i == 0)
index[i] = num++;
}
很棒!!
所以复杂度大概为19*2520*48*10(状态数*决策数)
我觉得这题状态的设计不能跟具体数字分开,否则会很难设计吧
所以用记忆化搜索,存起来
用具体数字去计算,重复的子问题跟pre关系比较密切
有一个比较重要的切入点就是LCM,还有%MOD缩小范围,才能存储
还有优化到只需%252的,更快
不过我觉得%2520比较好理解
代码:
const int MOD = ; LL dp[][MOD][];
int digit[];
int indx[MOD+]; void init() {
int num = ;
for(int i = ; i <= MOD; ++i) {
if(MOD%i == ) indx[i] = num++;
}
CL(dp, -);
} LL gcd(LL a, LL b) {
return b == ? a : gcd(b, a%b);
} LL lcm(LL a, LL b) {
return a/gcd(a, b)*b;
} LL dfs(int pos, int presum, int prelcm, bool edge) {
if(pos == -) return presum%prelcm == ;
if(!edge && dp[pos][presum][indx[prelcm]] != -)
return dp[pos][presum][indx[prelcm]];
int ed = edge ? digit[pos] : ;
LL ans = ;
for(int i = ; i <= ed; ++i) {
int nowlcm = prelcm;
int nowsum = (presum* + i)%MOD;
if(i) nowlcm = lcm(prelcm, i);
ans += dfs(pos - , nowsum, nowlcm, edge && i == ed);
}
if(!edge) dp[pos][presum][indx[prelcm]] = ans;
return ans;
} LL cal(LL x) {
CL(digit, );
int pos = ;
while(x) {
digit[pos++] = x%;
x /= ;
}
return dfs(pos - , , , );
} int main() {
//Read(); init();
int T;
LL a, b;
cin >> T;
while(T--) {
cin >> a >> b;
cout << cal(b) - cal(a - ) << endl;
}
return ;
}
Codeforces 55D Beautiful Number (数位统计)的更多相关文章
- FZU2179/Codeforces 55D beautiful number 数位DP
题目大意: 求 1(m)到n直接有多少个数字x满足 x可以整出这个数字的每一位上的数字 思路: 整除每一位.只需要整除每一位的lcm即可 但是数字太大,dp状态怎么表示呢 发现 1~9的LCM 是2 ...
- Codeforces 55D Beautiful Number
Codeforces 55D Beautiful Number a positive integer number is beautiful if and only if it is divisibl ...
- codeforces 55D - Beautiful numbers(数位DP+离散化)
D. Beautiful numbers time limit per test 4 seconds memory limit per test 256 megabytes input standar ...
- CodeForces - 55D - Beautiful numbers(数位DP,离散化)
链接: https://vjudge.net/problem/CodeForces-55D 题意: Volodya is an odd boy and his taste is strange as ...
- CodeForces - 55D Beautiful numbers —— 数位DP
题目链接:https://vjudge.net/problem/CodeForces-55D D. Beautiful numbers time limit per test 4 seconds me ...
- Codeforces - 55D Beautiful numbers (数位dp+数论)
题意:求[L,R](1<=L<=R<=9e18)区间中所有能被自己数位上的非零数整除的数的个数 分析:丛数据量可以分析出是用数位dp求解,区间个数可以转化为sum(R)-sum(L- ...
- codeforces 55D. Beautiful numbers 数位dp
题目链接 一个数, 他的所有位上的数都可以被这个数整除, 求出范围内满足条件的数的个数. dp[i][j][k], i表示第i位, j表示前几位的lcm是几, k表示这个数mod2520, 2520是 ...
- CodeForces 55D "Beautiful numbers"(数位DP+离散化处理)
传送门 参考资料: [1]:CodeForces 55D Beautiful numbers(数位dp&&离散化) 我的理解: 起初,我先定义一个三维数组 dp[ i ][ j ][ ...
- Codeforces 55D. Beautiful numbers(数位DP,离散化)
Codeforces 55D. Beautiful numbers 题意 求[L,R]区间内有多少个数满足:该数能被其每一位数字都整除(如12,24,15等). 思路 一开始以为是数位DP的水题,觉得 ...
随机推荐
- orcale 匿名代码块
declare cursor readflow_cur is select * from od_readflow t where t.flowid is null; l_emp od_readflow ...
- MongoDB安装及shell简介
MongoDB安装 MongoDB具有跨平台的优良特性,提供了对主流的操作系统支持,我们可以根据自己使用的操作系统,选择下载对应的安装包. 图 1. MongoDB支持各个版本的操作系统 MongoD ...
- 跟我一起学WCF(10)——WCF中事务处理
一.引言 好久没更新,总感觉自己欠了什么一样的,所以今天迫不及待地来更新了,因为后面还有好几个系列准备些,还有很多东西需要学习总结的.今天就来介绍下WCF对事务的支持. 二.WCF事务详解 2.1 事 ...
- 基于阿里云容器服务用docker容器运行ASP.NET 5示例程序
小试阿里云容器服务 之后,接下来有一个挡不住的小试冲动--用docker容器运行程序.首先想到的程序是 ASP.NET 5示例程序,于是参考msdn博客中的这篇博文 Running ASP.NET 5 ...
- 轻量级实用JQuery表单验证插件:validateForm5
表单验证是Web项目一个必不可少的环节,而且是一项重复的劳动,于是小菜封装了一款简单的表单验证插件,名字叫:validateForm5. validateForm5插件基于Jquery,并向HTML5 ...
- Visual Studio Developer Assistant 3月新功能展示
Visual Studio Developer Assistant 3月添加了以下新功能: https://visualstudiogallery.msdn.microsoft.com/a116671 ...
- 如何带领一个Android开发团队
1)重构,夜未眠 将框架从业务中剥离 如何提高开发效率 如何提高程序性能 单元测试 技术调研 代码版本管理 2)渠道包管理 自动打包工具 批量打渠道包的两种解决方案 定制渠道包的流程管理 3)稳定性, ...
- Spring AOP(配置文件方式)
spring配置文件: <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="h ...
- Atitit selenium3 新特性
Atitit selenium3 新特性 Selenium2.0 支持了webdriver api,,原来自己的api放弃了. Selenium v2.45.0 发布,支持Firefox 3 ...
- paip.自适应网页设计 跟 响应式 设计的区别跟原理and实践总结
paip.自适应网页设计 跟 响应式 设计的区别跟原理and实践总结 响应式Web设计(Responsive Web design)的理念是: 1 #-----------自适应布局VS响应式布局 2 ...