Codeforces 55D (数位DP+离散化+数论)
题目链接: http://poj.org/problem?id=2117
题目大意:统计一个范围内数的个数,要求该数能被各位上的数整除。范围2^64。
解题思路:
一开始SB地开了10维数组记录情况。
首先要求能被各位上的数整除,可以转化为被一个数整除问题。
这个数就是各位上数的最小公倍数LCM(不是GCD)。
其次,处理整除问题,得转化成数位DP的余数模板。1~9的LCM最大是2520, 那么%2520,让其可以开数组进行记忆化搜索。
最后, 对于不能%2520最后结果,再%各个数位累计过来的LCM。
这样下来,需要开20*2520*2520的数组,往CF上一交你会发现MLE。
仔细观察每次的LCM,其范围是1~2520没错,但是都是整除gcd的结果(LCM=a*b/gcd(a,b) ),也就是说所有LCM都是某个数的约数。
这个数其实就是2520。所以DP之前,为2520打个表,把LCM给离散化Hash。这样其实只有48个LCM了。数组开20*2520*50即可。
注意结果是int64。
#include "cstdio"
#include "cstring"
using namespace std;
#define LL long long
LL dp[][][],digit[],Hash[];
int gcd(int a,int b) {return b==?a:gcd(b,a%b);}
int lcm(int a,int b) {return a*b/gcd(a,b);}
LL dfs(int len,int Remain,int Lcm,bool fp)
{
if(!len) return Remain%Lcm?:;
printf("%d\n",Lcm);
if(!fp&&dp[len][Remain][Hash[Lcm]]!=-) return dp[len][Remain][Hash[Lcm]];
LL ret=,fpmax=fp?digit[len]:;
for(int i=;i<=fpmax;i++)
ret+=dfs(len-,(Remain*+i)%,i==?Lcm:lcm(Lcm,i),fp&&i==fpmax);
if(!fp) dp[len][Remain][Hash[Lcm]]=ret;
return ret;
}
LL f(long long x)
{
int len=;
while(x)
{
digit[++len]=x%;
x/=;
}
return dfs(len,,,true);
}
int main()
{
//freopen("in.txt","r",stdin);
int T;
LL l,r,cnt=;
scanf("%d",&T);
memset(dp,-,sizeof(dp));
for(int i=;i*i<=;i++)
{
if(%i==)
{
Hash[i]=cnt++;
if(i*i!=) Hash[/i]=cnt++;
}
}
while(T--)
{
scanf("%I64d%I64d",&l,&r);
LL res=f(r)-f(l-);
printf("%I64d\n",res);
}
}
| 2908091(#) | neopenx | CodeForces | 55D | Accepted | 19800 | 780 | GNU C++ 4.6 | 1121 |
2014-10-30 19:41:38
|
Codeforces 55D (数位DP+离散化+数论)的更多相关文章
- 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 #55D (数位dp+离散化)
Description Volodya is an odd boy and his taste is strange as well. It seems to him that a positive ...
- Codeforces 13C Sequence --DP+离散化
题意:给出一个 n (1 <= n <= 5000)个数的序列 .每个操作可以把 n 个数中的某一个加1 或 减 1.问使这个序列变成非递减的操作数最少是多少 解法:定义dp[i][j]为 ...
随机推荐
- 【OpenStack】OpenStack系列9之Compute节点安装
安装 安装参考: https://github.com/yongluo2013/osf-openstack-training/blob/master/installation/openstack-ic ...
- k Sum | & ||
k Sum Given n distinct positive integers, integer k (k <= n) and a number target. Find k numbers ...
- object-c 系列教程
1.object-c 基本数据类型 2.object-c 控制语句 3.object-c面向对象1 4.object-c面向对象2 5.object-c 继承多态 动态数据类型
- Java内存分配和内存管理
首先是概念层面的几个问题: Java中运行时内存结构有哪几种? Java中为什么要设计堆栈分离? Java多线程中是如何实现数据共享的? Java反射的基础是什么? 然后是运用层面: 引用类型变量和对 ...
- HDU 5512 Pagodas (gcd)
题目:传送门. 题意:t组数据,每组数据给定n,a,b,a!=b,在[1,n]的这些点中,每次选取a+b或a-b或b-a点,选取过的点在下次选取的时候可以当做ab来用继续选取,谁不能继续选取谁就输,问 ...
- iOS通过设置info.plist参数使用iTunes导入导出Documents目录下的文件
参考网址: http://my.oschina.net/hmj/blog/112592 http://www.cnblogs.com/taintain1984/archive/2013/05/27/3 ...
- redhad借用CentOs yum 安装
RedHat linux 默认是安装了yum软件的,但是由于激活认证的原因让redhat无法直接进行yum安装一些软件,如果我们需要在redhat下直接yum安装软件,我们只用把yum的源修改成Cen ...
- kvm NET 和 BRIDGE
net: <interface type='network'> <mac address='52:54:00:e1:ac:43'/> <source network='d ...
- tcp连接管理
[root@ok etc]# cat /proc/sys/net/core/netdev_max_backlog 每个网络接口接收数据包的速率比内核处理这些包的速率快时,允许送到队列的数据包的最大数目 ...
- C#开发微信公众平台-就这么简单(附Demo)(转载)
转载地址:http://www.cnblogs.com/xishuai/p/3625859.html 写在前面 服务号和订阅号 URL配置 创建菜单 查询.删除菜单 接受消息 发送消息(图文.菜单事件 ...