题目传送门

似乎我的解法和官方题解不太一样

纪念自己独立做出来的一道难度 2800 的题。

我们记 \(ans(x)\) 为 \([444...44,x]\) 的答案,显然答案为 \(ans(r)-ans(l)\)

其次我们考虑 \(a_i\) 与 \(a_{i+1}\) 之间有什么联系。

不难发现从 \(a_i\) 变到 \(a_{i+1}\),也就是把 \(a_i\) 末尾一系列 \(7\) 改为 \(4\),再把从右往左数第一个 \(4\) 改为 \(7\)。

这样我们就可以枚举末尾 \(7\) 的个数,假设为 \(cnt\)。

则 \(a_i=xxx...xx4777...77,a_{i+1}=xxx...xx7444...44\)

如果把前面 \(xxx...xx\) 记作 \(X\),那么 \(a_i=X \times 10^{cnt}+4777...77,a_{i+1}=X \times 10^{cnt}+7444...44\)

把 \(a_ia_{i+1}\) 暴力展开,即可得到一个关于 \(X\) 的二次三项式 \(AX^2+BX+C\),其中 \(A,B,C\) 是只与 \(cnt\) 有关的常数,它们具体是什么自己慢慢拆即可,这里就不再赘述了。。

接下来我们就要计算 \(X^2\) 的和,\(X\) 的和以及 \(X\) 的个数,显然可以数位 \(dp\) 预处理。

\(dp[i][0/1]\) 表示考虑到第 \(i\) 位,前 \(i\) 位是否达到上界的答案。

其中 \(dp[i][j]\) 中存三个值:平方和、和、以及个数。

转移可以从 \(dp[i-1][0/1]\) 中转移过来。再根据 \((10x+4)^2=100x^2+80x+16\),\((10x+7)^2=100x^2+140x+49\) 化简。

  1. /*
  2. Contest: -
  3. Problem: Codeforces 288E
  4. Author: tzc_wk
  5. Time: 2020.10.12
  6. */
  7. #include <bits/stdc++.h>
  8. using namespace std;
  9. #define fi first
  10. #define se second
  11. #define pb push_back
  12. #define fz(i,a,b) for(int i=a;i<=b;i++)
  13. #define fd(i,a,b) for(int i=a;i>=b;i--)
  14. #define foreach(it,v) for(__typeof(v.begin()) it=v.begin();it!=v.end();it++)
  15. #define all(a) a.begin(),a.end()
  16. #define fill0(a) memset(a,0,sizeof(a))
  17. #define fill1(a) memset(a,-1,sizeof(a))
  18. #define fillbig(a) memset(a,0x3f,sizeof(a))
  19. #define y1 y1010101010101
  20. #define y0 y0101010101010
  21. typedef pair<int,int> pii;
  22. typedef long long ll;
  23. const ll MOD=1e9+7;
  24. char s[100005];int n;
  25. struct data{
  26. ll sqr,cnt,sum;
  27. data(ll _sqr=0,ll _sum=0,ll _cnt=0){
  28. sqr=_sqr;sum=_sum;cnt=_cnt;
  29. }
  30. } dp[100005][2];
  31. ll pw[200005],seven[100005],four[100005];
  32. inline data upd4(data p){
  33. return data(
  34. (p.sqr*100ll+p.sum*80ll+p.cnt*16ll)%MOD,
  35. (p.sum*10ll+p.cnt*4ll)%MOD,(p.cnt));
  36. }
  37. inline data upd7(data p){
  38. return data(
  39. (p.sqr*100ll+p.sum*140ll+p.cnt*49ll)%MOD,
  40. (p.sum*10ll+p.cnt*7ll)%MOD,(p.cnt));
  41. }
  42. inline void add(data &x,data y){
  43. x.sqr+=y.sqr;if(x.sqr>=MOD) x.sqr-=MOD;
  44. x.sum+=y.sum;if(x.sum>=MOD) x.sum-=MOD;
  45. x.cnt+=y.cnt;if(x.cnt>=MOD) x.cnt-=MOD;
  46. }
  47. inline ll get(data x,ll k);
  48. inline ll calc(){
  49. scanf("%s",s+1);n=strlen(s+1);
  50. for(int i=0;i<=n;i++) dp[i][0]=dp[i][1]=data(0,0,0);
  51. dp[0][1]=data(0,0,1);
  52. for(int i=1;i<=n;i++){
  53. dp[i][0]=dp[i][1]=data(0,0,0);
  54. if(s[i]=='4'){
  55. add(dp[i][0],upd4(dp[i-1][0]));
  56. add(dp[i][0],upd7(dp[i-1][0]));
  57. add(dp[i][1],upd4(dp[i-1][1]));
  58. }
  59. else{
  60. add(dp[i][0],upd4(dp[i-1][0]));
  61. add(dp[i][0],upd4(dp[i-1][1]));
  62. add(dp[i][0],upd7(dp[i-1][0]));
  63. add(dp[i][1],upd7(dp[i-1][1]));
  64. }
  65. // printf("%lld %lld %lld\n",dp[i][0].sqr,dp[i][0].sum,dp[i][0].cnt);
  66. // printf("%lld %lld %lld\n",dp[i][1].sqr,dp[i][1].sum,dp[i][1].cnt);
  67. }
  68. ll ans=0;
  69. for(int i=0;i<n;i++){
  70. if(s[i+1]=='4'){
  71. ans=(ans+get(dp[i][0],n-i-1))%MOD;
  72. } else{
  73. ans=(ans+get(dp[i][0],n-i-1))%MOD;
  74. ans=(ans+get(dp[i][1],n-i-1))%MOD;
  75. }
  76. }
  77. // printf("%lld\n",ans);
  78. return ans;
  79. }
  80. int main(){
  81. pw[0]=1;for(int i=1;i<=200002;i++) pw[i]=pw[i-1]*10%MOD;
  82. for(int i=1;i<=100000;i++) seven[i]=(seven[i-1]*10+7)%MOD;
  83. for(int i=1;i<=100000;i++) four[i]=(four[i-1]*10+4)%MOD;
  84. ll L=calc(),R=calc();
  85. printf("%lld\n",(R-L+MOD)%MOD);
  86. return 0;
  87. }
  88. inline ll get(data x,ll k){
  89. // printf("%d %d %d\n",x.sqr,x.sum,x.cnt);
  90. return (seven[k]*four[k]%MOD*x.cnt%MOD+seven[k]*pw[k+1]%MOD*x.sum%MOD+
  91. seven[k]*7%MOD*pw[k]%MOD*x.cnt%MOD+four[k]*pw[k+1]%MOD*x.sum%MOD+
  92. four[k]*4%MOD*pw[k]%MOD*x.cnt%MOD+pw[(k<<1)+2]*x.sqr%MOD+
  93. 110*pw[k<<1]%MOD*x.sum%MOD+28*pw[k<<1]%MOD*x.cnt%MOD)%MOD;
  94. }

Codeforces 288E - Polo the Penguin and Lucky Numbers(数位 dp+推式子)的更多相关文章

  1. Codeforces 914 C. Travelling Salesman and Special Numbers (数位DP)

    题目链接:Travelling Salesman and Special Numbers 题意: 给出一个二进制数n,每次操作可以将这个数变为其二进制数位上所有1的和(3->2 ; 7-> ...

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

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

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

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

  4. Codeforces Beta Round #51 D. Beautiful numbers 数位dp

    D. Beautiful numbers Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/55/p ...

  5. Codeforces Gym 100418J Lucky tickets 数位DP

    Lucky ticketsTime Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://acm.hust.edu.cn/vjudge/contest/view ...

  6. Educational Codeforces Round 8 D. Magic Numbers 数位DP

    D. Magic Numbers 题目连接: http://www.codeforces.com/contest/628/problem/D Description Consider the deci ...

  7. Codeforces Gym100623J:Just Too Lucky(数位DP)

    http://codeforces.com/gym/100623/attachments 题意:问1到n里面有多少个数满足:本身被其各个数位加起来的和整除.例如120 % 3 == 0,111 % 3 ...

  8. CodeForces 628 D Magic Numbers 数位DP

    Magic Numbers 题意: 题意比较难读:首先对于一个串来说, 如果他是d-串, 那么他的第偶数个字符都是是d,第奇数个字符都不是d. 然后求[L, R]里面的多少个数是d-串,且是m的倍数. ...

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

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

随机推荐

  1. 设置elementUI的table组件滚动条位置

    1.设置table的ref为tableList 2.设置滚动至顶部 this.$refs.tableList.bodyWrapper.scrollTop =0; 3.设置滚动至底部 this.$ref ...

  2. vue如何监听数组的变化

    export function def (obj: Object, key: string, val: any, enumerable?: boolean) { Object.defineProper ...

  3. 想要彻底搞懂大厂是如何实现Redis高可用的?看这篇文章就够了!(1.2W字,建议收藏)

    高可用HA(High Availability)是分布式系统架构设计中必须考虑的因素之一,它通常是指,通过设计减少系统不能提供服务的时间. 假设系统一直能够提供服务,我们说系统的可用性是100%.如果 ...

  4. 玩转C语言链表-链表各类操作详解

    链表概述 链表是一种常见的重要的数据结构.它是动态地进行存储分配的一种结构.它可以根据需要开辟内存单元.链表有一个"头指针"变量,以head表示,它存放一个地址.该地址指向一个元素 ...

  5. 【做题记录】CF1451E2 Bitwise Queries (Hard Version)

    CF1451E2 Bitwise Queries (Hard Version) 题意: 有 \(n\) 个数( \(n\le 2^{16}\) ,且为 \(2\) 的整数次幂,且每一个数都属于区间 \ ...

  6. 查找最小生成树:克鲁斯克尔算法(Kruskal)算法

    一.算法介绍 Kruskal算法是一种用来查找最小生成树的算法,由Joseph Kruskal在1956年发表.用来解决同样问题的还有Prim算法和Boruvka算法等.三种算法都是贪心算法的应用.和 ...

  7. 转:Vivado IP报[Opt 31-67] 错误问题解决方法

    使用VIVADO编译代码时,其中一个IP报错,错误类似为 ImplementationOpt Design[Opt 31-67] Problem: A LUT2 cell in the design ...

  8. HttpContext.Current.Request.Url 地址:获取域名

    假设当前页完整地址是:http://www.test.com/aaa/bbb.aspx?id=5&name=kelli 协议名----http://域名  ---- www.test.com站 ...

  9. 攻防世界 WEB 高手进阶区 TokyoWesterns CTF shrine Writeup

    攻防世界 WEB 高手进阶区 TokyoWesterns CTF shrine Writeup 题目介绍 题目考点 模板注入 Writeup 进入题目 import flask import os a ...

  10. hivesql笔记

    一.常用聚合函数 count():计数 count(distinct 字段) 去重统计 sum():求合 avg():平均 max():最大值 min():最小值 二.hivesql执行顺序 from ...