题意:求[L,R](1<=L<=R<=9e18)区间中所有能被自己数位上的非零数整除的数的个数

分析:丛数据量可以分析出是用数位dp求解,区间个数可以转化为sum(R)-sum(L-1)前缀和相减的形式。如果一个数能被所有位上数的最小公倍数(lcm)整除,便是符合要求的数。

但是直接传递一个数n的话,dp数组肯定开不下。那么怎么让其传递的值更小呢。

先了解一个等式:  sum%(x*n)%x == sum%x

可以将一个数枚举到第pos位之前的值视作sum,x是所有位上数的lcm。那么我们可以在dfs递归的时候传递sum%(x*n),这样就能在维护sum%x性质的同时,使sum变得很小。

x*n怎么取呢?1-9的最小公倍数是2520,显然它作为此处的x*n在空间复杂度上是支持的。

此时可以确定dp数组是三维的。dp[i][j][k],其代表枚举到第i位,前面所有位组成的数%2520的余数是j,前面所有位上的lcm是k的数位状态下符合要求的个数。

还有一个问题,20*2520*2520的数组是开不下的。但是第三维有大部分的数都是不会出现的,所以可以对2520的因数离散化,数量是小于50的,空间复杂度是可以承受的。

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. const int maxn =;
  4. typedef long long ll;
  5. ll dp[maxn][][];
  6. int a[maxn];
  7. int dic[];
  8.  
  9. ll gcd(ll a,ll b)
  10. {
  11. if(b==) return a;
  12. return gcd(b,a%b);
  13. }
  14.  
  15. void init()
  16. {
  17. int MOD=,cnt=;
  18. for(int i=;i<=MOD;++i){
  19. if(MOD%i==)
  20. dic[i]=cnt++;
  21. }
  22. memset(dp,-,sizeof(dp));
  23. }
  24.  
  25. ll dfs(int pos,int mod=,int lcm = ,bool limit=true)
  26. {
  27. if (pos==-) return mod%lcm==;
  28. int id =dic[lcm];
  29. if(!limit && dp[pos][mod][id]!=-) return dp[pos][mod][id];
  30. int up = limit?a[pos]:;
  31. ll res=;
  32. for(int i=;i<=up;++i){
  33. if(i) res+=dfs(pos-,(mod*+i)%,lcm*i/gcd(lcm,i),limit && i==a[pos]);
  34. else res+=dfs(pos-,(mod*)%,lcm,limit && i==a[pos]);
  35. }
  36. if(!limit) dp[pos][mod][id] = res;
  37. return res;
  38. }
  39.  
  40. ll solve(ll n)
  41. {
  42. int pos=;
  43. while(n){
  44. a[pos++]=n%;
  45. n/=;
  46. }
  47. return dfs(pos-);
  48. }
  49.  
  50. int main()
  51. {
  52. #ifndef ONLINE_JUDGE
  53. freopen("in.txt","r",stdin);
  54. freopen("out.txt","w",stdout);
  55. #endif
  56. init();
  57. int T;
  58. scanf("%d",&T);
  59. while(T--){
  60. ll L,R;
  61. scanf("%lld%lld",&L,&R);
  62. printf("%lld\n",solve(R)-solve(L-));
  63. }
  64. return ;
  65. }

Codeforces - 55D Beautiful numbers (数位dp+数论)的更多相关文章

  1. codeforces 55D - Beautiful numbers(数位DP+离散化)

    D. Beautiful numbers time limit per test 4 seconds memory limit per test 256 megabytes input standar ...

  2. CodeForces - 55D - Beautiful numbers(数位DP,离散化)

    链接: https://vjudge.net/problem/CodeForces-55D 题意: Volodya is an odd boy and his taste is strange as ...

  3. CodeForces - 55D Beautiful numbers —— 数位DP

    题目链接:https://vjudge.net/problem/CodeForces-55D D. Beautiful numbers time limit per test 4 seconds me ...

  4. codeforces 55D. Beautiful numbers 数位dp

    题目链接 一个数, 他的所有位上的数都可以被这个数整除, 求出范围内满足条件的数的个数. dp[i][j][k], i表示第i位, j表示前几位的lcm是几, k表示这个数mod2520, 2520是 ...

  5. FZU2179/Codeforces 55D beautiful number 数位DP

    题目大意: 求  1(m)到n直接有多少个数字x满足 x可以整出这个数字的每一位上的数字 思路: 整除每一位.只需要整除每一位的lcm即可 但是数字太大,dp状态怎么表示呢 发现 1~9的LCM 是2 ...

  6. CF 55D. Beautiful numbers(数位DP)

    题目链接 这题,没想出来,根本没想到用最小公倍数来更新,一直想状态压缩,不过余数什么的根本存不下,看的von学长的blog,比着写了写,就是模版改改,不过状态转移构造不出,怎么着,都做不出来. #in ...

  7. CodeForces 55D "Beautiful numbers"(数位DP+离散化处理)

    传送门 参考资料: [1]:CodeForces 55D Beautiful numbers(数位dp&&离散化) 我的理解: 起初,我先定义一个三维数组 dp[ i ][ j ][ ...

  8. Codeforces 55D. Beautiful numbers(数位DP,离散化)

    Codeforces 55D. Beautiful numbers 题意 求[L,R]区间内有多少个数满足:该数能被其每一位数字都整除(如12,24,15等). 思路 一开始以为是数位DP的水题,觉得 ...

  9. 2018 ACM 国际大学生程序设计竞赛上海大都会赛重现赛 J Beautiful Numbers (数位DP)

    2018 ACM 国际大学生程序设计竞赛上海大都会赛重现赛 J Beautiful Numbers (数位DP) 链接:https://ac.nowcoder.com/acm/contest/163/ ...

随机推荐

  1. 把查询到结果合并放在一行 JOIN非union

    select one.max,one.min,one.low sts,c.high ens,one.time from ( select a.max max,a.min min,b.low low,a ...

  2. 使用scp命令传输文件

    1. 从远端复制文件到本地: sudo scp root@192.168.0.1:remote_path/remote_file . 2. 从本地复制文件到远端: sudo scp local_fil ...

  3. javascript基础语法及使用

    前几年自学过JavaScript,由于从事安卓开发,就放弃了对js的学习,今天又捡起来重新学习了下,希望对大家有所帮助. 首先介绍下什么是JavaScript. JavaScript 是互联网上最流行 ...

  4. 【python】pyqt练习

    import sys from PyQt4.QtCore import * from PyQt4.QtGui import * import ui_price class PriceDlg(QDial ...

  5. Hadoop1的安装

    目前hadoop1的稳定版本是1.2.1,我们以版本1.2.1为例详细的介绍hadoop1的安装,此过程包括OS安装与配置,JDK的安装,用户和组的配置,这些过程在hadoop2也有可能用到. Had ...

  6. python3----生成器generator(yield)

    # 列表推导式a = [i for i in range(100) if not(i % 2) and (i % 3)]print(a)# 字典推导式b = {i: i % 2 == 0 for i ...

  7. 【BZOJ3813】奇数国 线段树+欧拉函数

    [BZOJ3813]奇数国 Description 给定一个序列,每次改变一个位置的数,或是询问一段区间的数的乘积的phi值.每个数都可以表示成前60个质数的若干次方的乘积. Sample Input ...

  8. screen命令在freebsd安装和使用

    安装 # cd /usr/ports/sysutils/screen # make install clean 使用 # screen //以下^A表示同按“Ctrl + A”键 # ^A c //C ...

  9. CodeForces 670C Cinema(排序,离散化)

    C. Cinema time limit per test 2 seconds memory limit per test 256 megabytes input standard input out ...

  10. 高性能Web开发系列

    1. 高性能WEB开发基础 http://www.uml.org.cn/net/201404225.asp 2. 高性能WEB开发进阶(上) http://www.uml.org.cn/net/201 ...