CodeForces 55D-Beautiful numbers【数位DP+思维】

布满荆棘的人生 2023-08-17 17:37 237阅读 0赞

题目链接:https://codeforces.com/problemset/problem/55/D

题意:

Volodya 是一个古怪的男孩,他的品味与众不同。对他来说,一个正整数是 漂亮数 ,当且仅当它能够被自身的各非零数字整除。我们不必与之争辩,只需计算给定范围中有多少个漂亮数。

输入

输入的第一行包含了测试用例的数目 t (1 ≤ t ≤ 10)。接下来的 t 行,每行包含两个自然数 l**ir**i (1 ≤ l**i ≤ r**i ≤ 9 ·1018)。

思路:如果sum % kx == 0, 那么sum % x == 0, 所以我们考虑每位数的lcm,只要能够整除lcm就能整除所有位上的数。1~9的lcm是2520, 我们在数位dp时记录一下当前的数,个位数的公倍数,dp[i][j][k] 就表示枚举i位,当前数各位lcm是j,当前数是k的方案数,边界就是k % j == 0时为1,剩下的就是模板稍微修改一下了,对了,由于并不是所有的lcm都是满足条件的,所以我们要提前筛一下,就是离散化一下。

  1. #include<cstdio>
  2. #include<cstring>
  3. #include<iostream>
  4. #include<algorithm>
  5. using namespace std;
  6. typedef long long ll;
  7. #define ls rt << 1
  8. #define rs rt << 1|1
  9. #define mid ((l + r) >> 1)
  10. #define lson l, mid, ls
  11. #define rson mid + 1, r, rs
  12. const int maxn = 22;
  13. const int mod = 2520;
  14. ll dp[maxn][50][2525];
  15. int a[maxn], h[2525];
  16. ll gcd(ll a, ll b)
  17. {
  18. return b == 0 ? a : gcd(b, a % b);
  19. }
  20. ll dfs(int pos, int lcm, int num, int limit)
  21. {
  22. if(pos == 0) return num % lcm == 0;
  23. if(!limit && dp[pos][h[lcm]][num] != -1)
  24. return dp[pos][h[lcm]][num];
  25. int up = limit ? a[pos] : 9;
  26. ll ret = 0;
  27. for(int i = 0; i <= up; ++i)
  28. {
  29. ret += dfs(pos - 1, i ? i * lcm / gcd(i, lcm) : lcm, (num * 10 + i) % mod, limit && (i == up));
  30. }
  31. if(!limit)
  32. dp[pos][h[lcm]][num] = ret;
  33. return ret;
  34. }
  35. ll slove(ll x)
  36. {
  37. int tot = 0;
  38. while(x)
  39. {
  40. a[++tot] = x % 10;
  41. x /= 10;
  42. }
  43. return dfs(tot, 1, 0, 1);
  44. }
  45. int main()
  46. {
  47. int cnt = 0;
  48. for(int i = 1; i <= mod; ++i) //离散化一下
  49. if(mod % i == 0)
  50. h[i] = ++cnt;
  51. int t;
  52. scanf("%d", &t);
  53. memset(dp, -1, sizeof(dp)); //放在这里是为了以后的状态可以再利用
  54. while(t--)
  55. {
  56. ll x, y;
  57. scanf("%lld%lld", &x, &y);
  58. ll ans = slove(y) - slove(x - 1);
  59. printf("%lld\n", ans);
  60. }
  61. return 0;
  62. }

发表评论

表情:
评论列表 (有 0 条评论,237人围观)

还没有评论,来说两句吧...

相关阅读