数位 dp。

设 \(dp_{q,i}\)(\(i\in\{0,1,2,3,4,5,6,7,8,9\}\))为 \(1\sim q\) 中 \(i\) 出现的次数,\(1\sim q\) 的数字和显然就是 \(dp_{q,0}\times 0+dp_{q,1}\times 1+\cdots+dp_{q,i}\times i\cdots+dp_{q,9}\times 9\)。

所以我们只需要求出 \(1\sim q\) 中 \(i\) 出现的次数就能解决这个问题了。

这个问题看起来很好解决,但是注意前导零会影响结果,所以不能有前导零。

这该怎么办呢?

有前导零的式子很容易推出。有 \(q\) 位数字,\(i\) 数码的出现次数对于 \(x\in\{s\mid s\in \mathbb N,10^q\le s\le10^{q+1}\}\) ,\(f(q,i)\) 的数量都是相等的(设 \(f(q,i)\) 为 \(q\) 位数 \(i\) 数码的出现次数)。

具体求法罢,是:

\(\begin{cases}f(q,i)=0&q=0\\f(q,i)=10f(q-1)+10^{q-1}&q>0\end{cases}\)

我们考虑减去多余的 \(0\)。

我们先设数字为 \(\overline{A_1A_2A_3\dots A_n}\)

我们首先考虑求 \(\overline{A_100\dots 0}\),将 \(\overline{A_100\dots 0}\) 分割为区间 \([0000,1000),[1000,2000),\dots,[\overline{(A_1-1)00\dots 0},\overline{A_100\dots 0})\),所以答案就为 \(10^{n-1}A_1\),注意 \(<A_1\) 的每个数还出现了 \(10^{n-1}\) 次,所以要加上。

首位 \(A_1\) 出现了 \(\overline{A_2A_3\dots A_n}+1\) 次,答案还要加上 \(\overline{A_2A_3\dots A_n}+1\),

当然还需要处理前导 \(0\),用排列组合算一下会知道 \(i\) 位 \(q\) 个前导零的数量就是 \(10^q\)(\(q\in\{s\mid s\in\mathbb N,0\le s\le i-1\}\)),把它们加起来会发现一共出现了 \(10^{i-1}+10^{i-2}+...10\)(\(=\sum\limits_{k=0}^{i-1}10^k\)) 次,减一下即可。

Code:

#include<iostream>
#include<cstring>
using namespace std;
typedef long long ll;
const int N=51,MOD=1e9+7; //注意能 MOD 的地方都要 MOD,不然会 WA 0pts。
ll pow10[N],dp[N],a[N],count[N],tmpcount[N],ans;
// pow10 : 字面意思,10^n
// dp : 不考虑前导零的状况
// count : 统计 0~9 出现次数
// tmpcount : 暂时保存 count,用来减
// ans : 累加答案
void init() //预处理 pow10 和 dp。
{
pow10[0]=1;
for (int i=1;i<30;i++) dp[i]=(dp[i-1]*10%MOD+pow10[i-1])%MOD,pow10[i]=10*pow10[i-1]%MOD;
}
void solve(ll x)
{
int len=0;
while (x){a[++len]=x%10;x/=10;} //数位分离
for (int i=len;i>=1;i--) //从高到低遍历
{
for (int j=0;j<10;j++) count[j]+=dp[i-1]*a[i],count[j]%=MOD; //分割区间
for (int j=0;j<a[i];j++) count[j]+=pow10[i-1],count[j]%=MOD; //加上 10^(n-1)
ll lastnum=0;
for (int j=i-1;j>=1;j--) lastnum=lastnum*10+a[j],lastnum%=MOD; //求出 A2A3A4...An
count[a[i]]+=lastnum+1,count[a[i]]%=MOD;
count[0]-=pow10[i-1],count[0]=(count[0]+MOD)%MOD; //减去前导零
}
}
int main()
{
init();
ll l,r,T;
cin>>T;
for (int q=0;q<T;q++)
{
ans=0; cin>>l>>r;
solve(r); //前缀和思想相减 r 和 l-1。
for (int i=0;i<10;i++) (tmpcount[i]=count[i]),count[i]=0; //复制 count,记得清零
solve(l-1);
for (int i=0;i<10;i++) ans=(ans+i*(tmpcount[i]-count[i]+MOD)%MOD)%MOD,count[i]=0; //累加答案,记得清零 count。
cout<<ans<<'\n';
}
return 0;
}

Refence 求数字 \(i\) 出现的次数

题解 P4999 【烦人的数学作业】的更多相关文章

  1. P2602 [ZJOI2010]数字计数&P1239 计数器&P4999 烦人的数学作业

    P2602 [ZJOI2010]数字计数 题解 DFS 恶心的数位DP 对于这道题,我们可以一个数字一个数字的求 也就是分别统计区间 [ L , R ] 内部数字 i 出现的次数 (0<=i&l ...

  2. [洛谷P4999]烦人的数学作业

    题目大意:定义$f(x)$表示$x$每一个数位(十进制)的数之和,求$\sum\limits_{i=l}^rf(i)$,多组询问. 题解:数位$DP$,可以求出每个数字的出现个数,再乘上每个数字的大小 ...

  3. luoguP4999 烦人的数学作业

    写在前面 这两天信息量有点大,需要好好消化一下,呼呼 \(f[i][j]\) 的转移式还是好理解的,但是对于其实际意义课上有点糊 求 \(ans_{1, x}\) 是感觉手动把数拆开看会好理解一点?? ...

  4. BZOJ-2326 数学作业 矩阵乘法快速幂+快速乘

    2326: [HNOI2011]数学作业 Time Limit: 10 Sec Memory Limit: 128 MB Submit: 1564 Solved: 910 [Submit][Statu ...

  5. SID1190471 / 烦人的幻灯片 暴力出奇迹 !!!!!!!!!!!!!!!!!!

    PID221 / 烦人的幻灯片 ☆ 提交你的代码 查看讨论和题解 你还木有做过哦 我的状态         查看最后一次评测记录 质量还不能统计出来哦~ 题目评价 质量 无 ★★★★★ ★★★★☆ ★ ...

  6. 得物(毒)APP,8位抽奖码需求,这不就是产品给我留的数学作业!

    作者:小傅哥 博客:https://bugstack.cn Github:https://github.com/fuzhengwei/CodeGuide/wiki 沉淀.分享.成长,让自己和他人都能有 ...

  7. sdibt 1244 烦人的幻灯片

    在这个OJ站还没号,暂时没提交,只是过了样例 真不愧是烦人的幻灯片,烦了我一小时 ---更新:OJ测试完毕,AC 烦人的幻灯片问题 Time Limit: 1 Sec  Memory Limit: 6 ...

  8. bzoj2326: [HNOI2011]数学作业

    矩阵快速幂,分1-9,10-99...看黄学长的代码理解...然而他直接把答案保存在最后一行(没有说明...好吧应该是我智障这都不知道... #include<cstdio> #inclu ...

  9. BZOJ 2326: [HNOI2011]数学作业( 矩阵快速幂 )

    BZOJ先剧透了是矩阵乘法...这道题显然可以f(x) = f(x-1)*10t+x ,其中t表示x有多少位. 这个递推式可以变成这样的矩阵...(不会用公式编辑器...), 我们把位数相同的一起处理 ...

随机推荐

  1. Java学习笔记-基础语法Ⅵ-异常

    异常 对于异常,JVM默认处理方案为:把异常名称.异常原因以及异常出现的位置等信息输出在控制台,并且程序停止执行 异常处理方式一:try ... catch public class Demo { p ...

  2. apache tomcat 目录session应用信息漏洞

    Tomcat 是一款开源的 Web 应用服务器软件.Tomcat 属于轻量级应用服务器,在中小型系统和并发访问用户不多的场合下被普遍使用,是开发和调试 JSP 程序的首选. 漏洞描述 apache T ...

  3. CTF简介

    最近在学习渗透测试,后来发现CTF很有趣,发现对学习有所帮助,于是找了几个网站,下面推荐几个我觉得不错的网站 https://www.ctfhub.com/#/index https://adworl ...

  4. Cubieboard安装系统

    2013年买的一个小玩意. 一.硬件 1.1 相关资料 http://www.cubieforums.com http://cubie.cc 1.2 cubieboard1 1.3 无线网卡 水星 M ...

  5. flex布局的总结

    1.开启了flex布局的元素叫: flex container 2.里面的直接子元素叫:flex items(默认情况下,所有item都会在一行显示) 3.display属性由flex和inline- ...

  6. Docker安装Mycat和Mysql进行水平分库分表实战【图文教学】

    一.前言 小编最近公司有个新的需求,数据量比较大,要涉及到分库分表.大概了解了一些主流的中间件,使用和网上资料比较多的是Mycat和sharding-jdbc,小编比较倾向于Mycat.原因很简单就是 ...

  7. 【转】理解 CI 和 CD 之间的区别

    有很多关于持续集成(CI)和持续交付(CD)的资料.很多文章用技术术语来进行解释,以及它们怎么帮助你的组织.可惜的是,在一些情况下,这些方法通常与特定工具.甚至供应商相关联.在公司食堂里非常常见的谈话 ...

  8. 一个 curl 配置引发的惨案

    问题 这两天想装新版本的 node,发现 nvm 一直报下面这个错误.我反复 Google 了,但是并没有找到一条我能用的. 痛苦 我起初一直怀疑是我用的 zsh-nvm 抽疯,所以今天有空就把它还有 ...

  9. QT 基于QScrollArea的界面嵌套移动

    在实际的应用场景中,经常会出现软件界面战场图大于实际窗体大小,利用QScrollArea可以为widget窗体添加滚动条,可以实现小窗体利用滚动条显示大界面需求.实现如下: QT创建一个qWidget ...

  10. Redis实现延迟队列的正确姿势

    在之前探讨延时队列的文章中我们提到了 redisson delayqueue 使用 redis 的有序集合结构实现延时队列,遗憾的是 go 语言社区中并无类似的库.不过问题不大,没有轮子我们自己造. ...