Codeforces #55D (数位dp+离散化)
Description
Volodya is an odd boy and his taste is strange as well. It seems to him that a positive integer number is beautiful if and only if it is divisible by each of its nonzero digits. We will not argue with this and just count the quantity of beautiful numbers in given ranges.
Input
The first line of the input contains the number of cases t (1 ≤ t ≤ 10). Each of the next t lines contains two natural numbers li and ri (1 ≤ li ≤ ri ≤ 9 ·1018).
Please, do not use %lld specificator to read or write 64-bit integers in C++. It is preffered to use cin (also you may use %I64d).
Output
Output should contain t numbers — answers to the queries, one number per line — quantities of beautiful numbers in given intervals (from li to ri, inclusively).
Sample Input
1
1 9
9
1
12 15
2 让你找[l,r]区间中,能被自己各个非零数位整除的数的个数。一看就是满足区间减法。现在就讨论怎么求就行了。
首先lcm(1..9)=2520, int MOD=2520;保存每一个数是不现实的,所以我们就.保存x%MOD就行了。
preSum表示已经讨论的前面的几个数位的值(前串),preLcm表示前穿的Lcm。
这里注意到1...9的各种lcm可以离散化处理,只有48个,这样可以大大减少数组的空间。
我们再用flag来表示当前位的数字大小是否超过x对应位的大小
例:x=15666;当我们讨论到千位是1,2,3,4时,后面三位是随便选的,讨论千位是5是,百位就不能随便选了,要<=6,此时在千位我们就达到了边界。
剩下的交给dfs。
PS:有人把2520优化成252的,92ms过了...我1122ms...
代码如下:
#include <bits/stdc++.h> using namespace std; const int MAXN=;
const int MOD=;
long long dp[MAXN][MOD][];//dp[i][j][k]表示处理到第i位,前串数(取模后)是j,前串树lcm是k时,后面位随便变的合法情况的个数
int index[MOD+],bit[MAXN];//index表示1..9的各种组合lcm,bit是将数字的每一位拆开保存
long long int gcd (long long int a,long long int b) {return (b==)?a:gcd(b,a%b);}
long long int lcm (long long int a,long long int b){return a/gcd(a,b)*b;}
void init()//来找1...9之间各种组合的lcm
{
int num=;
for (int i=;i<=MOD;++i)
if (MOD%i==)
index[i]=num++;
}
long long dfs (int pos,int preSum,int preLcm,bool flag)//pos当前位,flag前面几位是否达到边界
{
if (pos==-)//讨论到最后一位
return preSum%preLcm==;//如果这个数满足要求,+1
if (!flag && dp[pos][preSum][index[preLcm]]!=-)//没达到边界而且访问过这个状态
return dp[pos][preSum][index[preLcm]];//直接return,记忆化搜索
long long ans=;
int endd=flag?bit[pos]:;//这位达到边界时,下一位从0到x的对应位变化。没达到边界是0...9变化
for (int i=;i<=endd;i++)
{
int nowSum=(preSum*+i)%MOD;//添加下一位数字,然后更新状态
int nowLcm=preLcm;
if (i)
nowLcm=lcm(nowLcm,i);
ans+=dfs(pos-,nowSum,nowLcm,flag&&i==endd);
}
if (!flag)
dp[pos][preSum][index[preLcm]]=ans;
return ans;
}
long long calc (long long x)
{
memset(bit,,sizeof bit);
int pos=;
while (x)
{
bit[pos++]=x%;
x/=;
}
return dfs(pos-,,,);
}
int main()
{
int t;
long long int l,r;
init();
memset(dp,-,sizeof dp);
scanf("%d",&t);
while (t--)
{
scanf("%I64d%I64d",&l,&r);
printf("%I64d\n",calc(r)-calc(l-));
}
return ;
}
Codeforces #55D (数位dp+离散化)的更多相关文章
- Codeforces 55D (数位DP+离散化+数论)
题目链接: http://poj.org/problem?id=2117 题目大意:统计一个范围内数的个数,要求该数能被各位上的数整除.范围2^64. 解题思路: 一开始SB地开了10维数组记录情况. ...
- codeforces 55D 数位dp
D. Beautiful numbers time limit per test 4 seconds memory limit per test 256 megabytes input standar ...
- CodeForces 55D "Beautiful numbers"(数位DP+离散化处理)
传送门 参考资料: [1]:CodeForces 55D Beautiful numbers(数位dp&&离散化) 我的理解: 起初,我先定义一个三维数组 dp[ i ][ j ][ ...
- codeforces 55D - Beautiful numbers(数位DP+离散化)
D. Beautiful numbers time limit per test 4 seconds memory limit per test 256 megabytes input standar ...
- Codeforces 628D 数位dp
题意:d magic number(0<=d<9)的意思就是一个数,从最高位开始奇数位不是d,偶数位是d 题目问,给a,b,m,d(a<=b,m<2000)问,a,b之间有多少 ...
- codeforces 401D (数位DP)
思路:很明显的数位dp,设dp[i][j] 表示选取数字的状态为i,模m等于j的数的个数,那么最后的答案就是dp[(1<<n)-1][0].状态转移方程就是,dp[i|(1<< ...
- Travelling Salesman and Special Numbers CodeForces - 914C (数位dp)
大意: 对于一个数$x$, 每次操作可将$x$变为$x$二进制中1的个数 定义经过k次操作变为1的数为好数, 求$[1,n]$中有多少个好数 注意到n二进制位最大1000位, 经过一次操作后一定变为1 ...
- Codeforces - 914C 数位DP
题意有点难以描述,简略的就是给定一个二进制\(n\),每一步操作能使\(n\)的位为1的数的和转化为一个十进制,然后转化为该数的二进制再进行相同的操作 查询\([0,n]\)中操作数恰好为\(k\)的 ...
- Codeforces 13C Sequence --DP+离散化
题意:给出一个 n (1 <= n <= 5000)个数的序列 .每个操作可以把 n 个数中的某一个加1 或 减 1.问使这个序列变成非递减的操作数最少是多少 解法:定义dp[i][j]为 ...
随机推荐
- 【Java】Java引用maven私服jar包及jar包提交私服问题
pom.xml中加入以下配置即可 1.引用私服jar包 <!-- 加载的是 第三方项目使用的jar包 --> <repositories> <repository> ...
- BZOJ 2806: [Ctsc2012]Cheat(单调队列优化dp+后缀自动机)
传送门 解题思路 肯定先要建出来广义后缀自动机.刚开始以为是个二分+贪心,写了一下结果\(20\)分.说一下正解,首先显然\(L_0\)具有单调性,是可以二分的.考虑二分后怎样判合法,对于分割序列很容 ...
- JS继承 实现方式
JS中继承方式的实现有多种方法,下面是比较推荐的方法,其它继承方式可做了解: function object(o) { function F() {} F.prototype = o; return ...
- static、final修饰的变量和方法能否被继承的问题
首先定义父类和子类 public class Parent { protected static String a = "static"; final String b = &qu ...
- (转)VirtualBox下安装CentOS7系统
转:https://www.cnblogs.com/hihtml5/p/8217062.html 本文假定你已经知道如何安装VirtualBox虚拟机软件,并且已经安装好了. 首先我们需要准备好cen ...
- pycharm运行html文件报404错误
某次发现运行导入的html文件的时候,打开浏览器会报404错误: 而运行自己写的html文件则正常显示: 最后发现这是pycharm缓存问题,只需重启pycharm清除缓存就ok啦!
- gradle 国内加速,修改镜像源
为什么慢 由于默认情况下执行 gradle 各种命令是去国外的 gradle 官方镜像源获取需要安装的具体软件信息,所以在不使用代理.不翻墙的情况下,从国内访问国外服务器的速度相对比较慢 如何修改镜像 ...
- python 访问 网页 获得源码
>>> from urllib.request import urlopen >>> for line in urlopen('http://tycho.usno. ...
- 大数据给IT企业带来攫金市场新机遇
大数据给IT企业带来攫金市场新机遇 大数据,一个时髦的名词,也是当下热门的业务领域.大数据诱人的利益诉求点之一,即通过大数据能更好地提高效率,更好地有的放矢.一方面,大数据让公司内部更有效地运作:另一 ...
- Junit简单使用
上篇文章也说到了,接口测试我使用的是Junit框架.因为我还是刚刚接触,也还没有深入了解,主要学会了断言的使用.断言是对测试运行结果的判断,如果结果符合要求,程序就会继续执行下去.反之,如果结果和预计 ...