CodeForces - 55D Beautiful numbers(数位DP+Hash)题解
题意:美丽数定义:一个正数能被所有位数整除。求给出一个范围,回答这个范围内的美丽数。
思路:一个数能被所有位数整除,换句话说就是一个数能整除所有位数的LCM,所以问题就转化为一个数能否被所有位数的LCM整除。按照一般的思想,直接开三维dp[pos][num][lcm]。但是num范围很大,直接开就爆了,怎么办呢?我们可以把num%2520(即1~9的LCM)储存为mod,因为所有位数最大的LCM就是2520,所以可以mod 2520。然后你很开心的开了dp[pos][2520][2520],然后你又爆了...
然后你可以发现虽然LCM最大是2520,但是没有一个LCM是2519这样的数字,这样就有很多空间浪费,打个表可以发现,1~9的LCM其实就48个数字,我们把这48个数字Hash一下保存,那么就缩小到了dp[pos][2520][48]。
然后你就可以A了
友谊赛被打爆了,水题都不会了
代码:
#include<cstdio>
#include<map>
#include<set>
#include<vector>
#include<cstring>
#include<string>
#include<cmath>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#define ll long long
const int N = 50000+5;
const int INF = 0x3f3f3f3f;
using namespace std;
int dig[20];
ll dp[20][2550][50],Hash[2550];
ll Gcd(ll a,ll b){
return b == 0? a : Gcd(b,a%b);
}
ll Lcm(ll a,ll b){
return a * b / Gcd(a,b);
}
ll dfs(int pos,int mod,int lcm,bool limit){
if(pos == -1) return mod % lcm == 0? 1 : 0;
if(!limit && dp[pos][mod][Hash[lcm]] != -1) return dp[pos][mod][Hash[lcm]];
int top = limit? dig[pos] : 9;
ll ret = 0;
for(int i = 0;i <= top;i++){
int MOD = (mod*10 + i) % 2520;
int LCM;
if(i) LCM = Lcm(i,lcm);
else LCM = lcm;
ret += dfs(pos - 1,MOD,LCM,limit && i == top);
}
if(!limit) dp[pos][mod][Hash[lcm]] = ret;
return ret;
}
ll solve(ll x){
int pos = 0;
while(x){
dig[pos++] = x % 10;
x /= 10;
}
ll ret = dfs(pos- 1,0,1,true);
return ret;
}
int main(){
int T;
ll l,r,cnt = 0;
scanf("%d",&T);
memset(dp,-1,sizeof(dp));
for(int i = 1;i*i <= 2520;i++){ //hash
if(2520 % i == 0){
Hash[i] = cnt++;
if(i*i != 2520){
Hash[2520 / i] = cnt++;
}
}
}
while(T--){
scanf("%I64d%I64d",&l,&r);
printf("%I64d\n",solve(r) - solve(l - 1));
}
return 0;
}
CodeForces - 55D Beautiful numbers(数位DP+Hash)题解的更多相关文章
- 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是 ...
- FZU2179/Codeforces 55D beautiful number 数位DP
题目大意: 求 1(m)到n直接有多少个数字x满足 x可以整出这个数字的每一位上的数字 思路: 整除每一位.只需要整除每一位的lcm即可 但是数字太大,dp状态怎么表示呢 发现 1~9的LCM 是2 ...
- CF 55D. Beautiful numbers(数位DP)
题目链接 这题,没想出来,根本没想到用最小公倍数来更新,一直想状态压缩,不过余数什么的根本存不下,看的von学长的blog,比着写了写,就是模版改改,不过状态转移构造不出,怎么着,都做不出来. #in ...
- 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的水题,觉得 ...
- 2018 ACM 国际大学生程序设计竞赛上海大都会赛重现赛 J Beautiful Numbers (数位DP)
2018 ACM 国际大学生程序设计竞赛上海大都会赛重现赛 J Beautiful Numbers (数位DP) 链接:https://ac.nowcoder.com/acm/contest/163/ ...
随机推荐
- synchronized同步方法
“非线程安全”其实会在多个线程对同一个对象中的实例变量进行并发访问的时候产生,产生的后果是脏读,也就是取到的数据是被更改过的.而“线程安全”就是以获得的实例变量的值是经过同步处理的,不会出现脏读的现象 ...
- poj2096 Collecting Bugs[期望dp]
Collecting Bugs Time Limit: 10000MS Memory Limit: 64000K Total Submissions: 5394 Accepted: 2670 ...
- shell中特殊变量$0 $1 $# $$ $! $?的涵义
$0: 执行脚本的名字 $*和$@: 将所有参数返回 $#: 参数的个数 $_: 代表上一个命令的最后一个参数 $$: 代表所在命令的PID $!: 代表最后执行的后台命令的PID $?: 代表上一个 ...
- python随机验证码函数
#验证码函数def yzm(i): code = [] for i in range(i): ,): code.append(str(random.randint(,))) else: tmp = r ...
- CHECKSUM比较两表字段值差异
CHECKSUM 返回在表的行上或在表达式列表上计算的校验值.CHECKSUM 用于生成哈希索引. 语法 CHECKSUM ( * | expression [ ,...n ] ) 参数 * 指定在表 ...
- 强连通分量+缩点(poj2553)
http://poj.org/problem?id=2553 The Bottom of a Graph Time Limit: 3000MS Memory Limit: 65536K Total ...
- 树链剖分-点的分治(链的点的个数为k的点对数)
hdu4760 Cube number on a tree Time Limit: 20000/10000 MS (Java/Others) Memory Limit: 65535/65535 ...
- JAVA内存构成详解
java memory = direct memory(直接内存) + jvm memory(MaxPermSize +Xmx) 1)直接内存跟堆 直接内存则是一块由程序本身管理的一块内存空间,它 ...
- c#字符串切割split使用方法
string strtest = "asdfg12wertgv1287654" "}, StringSplitOptions.RemoveEmptyEntries); 结 ...
- C#学习笔记之(Hellow,WORLD;常量和变量;键盘输入和输出;数据类型转换;计算器)
HELLO,WORLD Console.Write 表示向控制台直接写入字符串,不进行换行,可继续接着前面的字符写入. Console.WriteLine 表示向控制台写入字符串后换行. Consol ...