codeforces55D数位dp
查询给定区间内的beautiful number。 一个数字是beautiful number当且仅当能被自己的各个数字不为0的位整除。
这个dp的状态还是挺难想的。一个数能被自己的各个位整除,那么必须是这些位的最小公倍数的倍数。
那么可以想到的一个状态是dp[i][j][k] 为长度为i的时候,数字是组成的数字是j,各个位的最小公倍数是k, 那么当j%k==0,说明数字j是可行的。
当时j太大了,根本存不下。但是数字1-->9最大的一个最小公倍数是2520, 所以只要 j%2520%k==0就行了。
这是为什么呢 ,因为j可以分解为(k*2520 + x) % k , x=j%2520, 所以只要判断x%k是不是等于0就行了。
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <algorithm>
#include <iostream>
#include <queue>
#include <stack>
#include <vector>
#include <map>
#include <set>
#include <string>
#include <math.h>
using namespace std;
#pragma warning(disable:4996)
#pragma comment(linker, "/STACK:1024000000,1024000000")
typedef __int64 LL;
const int mod = ;
const int INF = <<;
/*
dp[i][j][k]
表示前取了前i位,数字为j,各个位的最小公倍数位k
如果j%k==0 那么说明可以 dp[i+1][j*10 + i][lcm(k,i)] = dp[i][j][k] */ LL dp[][][];
int num[];
bool vis[];
int hs[ + ];
int gcd(int a, int b)
{
if (b == )return a;
return gcd(b, a%b);
}
int lcm(int a, int b)
{
return a*b / gcd(a, b);
}
void init()
{
int cnt = ;
for (int i = ; i <= mod; ++i)
if (mod%i == )
hs[i] = cnt++;
} LL dfs(int pos, int preSum, int preLcm, bool flag)
{
if (pos == )return preSum % preLcm==;
if (!flag && dp[pos][preSum][hs[preLcm]] != -)
return dp[pos][preSum][hs[preLcm]];
int limit = flag ? num[pos] : ;
LL ans = ;
for (int i = ; i <= limit; ++i)
{
int nowSum = (preSum * + i) % mod;
int nowLcm = preLcm;
if (i)nowLcm = lcm(nowLcm, i);
ans += dfs(pos - , nowSum, nowLcm, flag&&i == limit);
}
if (!flag)//如果pos为比n的第pos位小,那么说明可以利用已有的结果,如果不是的话,不能,因为可能比n大
dp[pos][preSum][hs[preLcm]] = ans;
return ans;
}
LL calc(LL n)
{ int len = ;
while (n)
{
num[++len] = n % ;
n /= ;
} return dfs(len,,,);
}
int main()
{
init();
int t;
LL l, r;
memset(dp, -, sizeof(dp));//只初始化一次,因为计算的结果可多次利用
scanf("%d", &t);
while (t--)
{
scanf("%I64d%I64d", &l, &r);
printf("%I64d\n", calc(r) - calc(l-));
}
return ;
}
codeforces55D数位dp的更多相关文章
- 数位DP入门
HDU 2089 不要62 DESC: 问l, r范围内的没有4和相邻62的数有多少个. #include <stdio.h> #include <string.h> #inc ...
- CodeForces - 55D - Beautiful numbers(数位DP,离散化)
链接: https://vjudge.net/problem/CodeForces-55D 题意: Volodya is an odd boy and his taste is strange as ...
- 【BZOJ1662】[Usaco2006 Nov]Round Numbers 圆环数 数位DP
[BZOJ1662][Usaco2006 Nov]Round Numbers 圆环数 Description 正如你所知,奶牛们没有手指以至于不能玩"石头剪刀布"来任意地决定例如谁 ...
- bzoj1026数位dp
基础的数位dp 但是ce了一发,(abs难道不是cmath里的吗?改成bits/stdc++.h就过了) #include <bits/stdc++.h> using namespace ...
- uva12063数位dp
辣鸡军训毁我青春!!! 因为在军训,导致很长时间都只能看书yy题目,而不能溜到机房鏼题 于是在猫大的帮助下我发现这道习题是数位dp 然后想起之前讲dp的时候一直在补作业所以没怎么写,然后就试了试 果然 ...
- HDU2089 不要62[数位DP]
不要62 Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submis ...
- 数位DP GYM 100827 E Hill Number
题目链接 题意:判断小于n的数字中,数位从高到低成上升再下降的趋势的数字的个数 分析:简单的数位DP,保存前一位的数字,注意临界点的处理,都是套路. #include <bits/stdc++. ...
- 数位dp总结
由简单到稍微难点. 从网上搜了10到数位dp的题目,有几道还是很难想到的,前几道基本都是模板题,供入门用. 点开即可看题解. hdu3555 Bomb hdu3652 B-number hdu2089 ...
- 数位DP之奥义
恩是的没错数位DP的奥义就是一个简练的dfs模板 int dfs(int position, int condition, bool boundary) { ) return (condition ? ...
随机推荐
- Net 并行知识学习
园子里有很多介绍并行库TPL的这里列举2个 1 并行之Task讲解:http://www.cnblogs.com/yanyangtian/archive/2010/05/21/1741193.html ...
- Delphi中使用GDI+进行绘图(1)
Delphi的VCL类库中,默认使用的是GDI绘图接口,该接口封装了Win32 GDI接口,能够满足基本的绘图功能,但如果要实现更高级的绘图功能,往往比较困难,GDI+是微软在GDI之后的一个图形接口 ...
- Mysql RR隔离更新列没有索引 会锁全表
<pre name="code" class="html">mysql> show variables like '%tx_isolation ...
- MySQL 执行计划里的rows
<pre name="code" class="html">SQL> alter session set statistics_level=a ...
- javascript实现图片无缝滚动(scrollLeft的使用方法介绍)
<!DOCTYPE html > <html> <head> <meta http-equiv="Content-Type" conten ...
- Spring Security Source Code -- 验证标准流程
除了初始阶段: 主干验证流程链: MyInvocationSecurityMetadataSource.getAttributes(Object) line: 43 MyFilterSecur ...
- 注解框架---AndroidAnnotations
AndroidAnnotations是一个开源框架,旨在加快Android开发的效率.通过使用它开放出来的注解api,你差点儿可以使用在不论什么地方, 大大的降低了无关痛痒的代码量,让开发人员可以抽身 ...
- linux route命令的使用详解
route命令用于显示和操作IP路由表.要实现两个不同的子网之间的通信,需要一台连接两个网络的路由器,或者同时位于两个网络的网关来实现.在Linux系统中,设置路由通常是 为了解决以下问题:该Linu ...
- 解决Delphi MDI 闪烁问题(使用WM_SETREDRAW锁屏后进行处理)
procedure TMainForm.CreateMDIChild(const Name: string); var Child: TMDIChild; begin { create a new M ...
- QLineEdit 自动完成(使用setCompleter,内含一个ListView)
-------------------------------------CompleteLineEdit.h------------------------------------- #ifndef ...