题解 P4999 【烦人的数学作业】
数位 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 【烦人的数学作业】的更多相关文章
- P2602 [ZJOI2010]数字计数&P1239 计数器&P4999 烦人的数学作业
P2602 [ZJOI2010]数字计数 题解 DFS 恶心的数位DP 对于这道题,我们可以一个数字一个数字的求 也就是分别统计区间 [ L , R ] 内部数字 i 出现的次数 (0<=i&l ...
- [洛谷P4999]烦人的数学作业
题目大意:定义$f(x)$表示$x$每一个数位(十进制)的数之和,求$\sum\limits_{i=l}^rf(i)$,多组询问. 题解:数位$DP$,可以求出每个数字的出现个数,再乘上每个数字的大小 ...
- luoguP4999 烦人的数学作业
写在前面 这两天信息量有点大,需要好好消化一下,呼呼 \(f[i][j]\) 的转移式还是好理解的,但是对于其实际意义课上有点糊 求 \(ans_{1, x}\) 是感觉手动把数拆开看会好理解一点?? ...
- BZOJ-2326 数学作业 矩阵乘法快速幂+快速乘
2326: [HNOI2011]数学作业 Time Limit: 10 Sec Memory Limit: 128 MB Submit: 1564 Solved: 910 [Submit][Statu ...
- SID1190471 / 烦人的幻灯片 暴力出奇迹 !!!!!!!!!!!!!!!!!!
PID221 / 烦人的幻灯片 ☆ 提交你的代码 查看讨论和题解 你还木有做过哦 我的状态 查看最后一次评测记录 质量还不能统计出来哦~ 题目评价 质量 无 ★★★★★ ★★★★☆ ★ ...
- 得物(毒)APP,8位抽奖码需求,这不就是产品给我留的数学作业!
作者:小傅哥 博客:https://bugstack.cn Github:https://github.com/fuzhengwei/CodeGuide/wiki 沉淀.分享.成长,让自己和他人都能有 ...
- sdibt 1244 烦人的幻灯片
在这个OJ站还没号,暂时没提交,只是过了样例 真不愧是烦人的幻灯片,烦了我一小时 ---更新:OJ测试完毕,AC 烦人的幻灯片问题 Time Limit: 1 Sec Memory Limit: 6 ...
- bzoj2326: [HNOI2011]数学作业
矩阵快速幂,分1-9,10-99...看黄学长的代码理解...然而他直接把答案保存在最后一行(没有说明...好吧应该是我智障这都不知道... #include<cstdio> #inclu ...
- BZOJ 2326: [HNOI2011]数学作业( 矩阵快速幂 )
BZOJ先剧透了是矩阵乘法...这道题显然可以f(x) = f(x-1)*10t+x ,其中t表示x有多少位. 这个递推式可以变成这样的矩阵...(不会用公式编辑器...), 我们把位数相同的一起处理 ...
随机推荐
- grafana展示zabbix统计
1.安装grafana 参照官网文档:https://grafana.com/grafana/download 我这边是centos系统,执行这两个命令 wget https://dl.grafa ...
- 893. Groups of Special-Equivalent Strings - LeetCode
Question 893. Groups of Special-Equivalent Strings Solution 题目大意: AB两个字符串相等的条件是:A中偶数位出现的字符与B中偶数位出现的字 ...
- unity---小地图制作
脚本控制移动 public float moveSpeed =5f; public float roundSpeed=120f; void Update() { this.transform.Tran ...
- CentOS7 单节点和多节点 HPL测试
前置工作:安装OpenBLAS; 安装Mpich (可参考首页博客) 官网下载压缩包到/opt目录 cd /opt && wget https://www.netlib.org/ben ...
- linux系统下文件误删除该如何恢复?
一.linux误删除数据的场景 在实际的工作中,朋友们可能会将linux服务器上的文件不小心误删除掉了.而且越是资历老的工程师越容易犯这样的错误,敲代码的速度也是够快,啪啪rm -rf一个回车,然后就 ...
- CF1625D - Binary Spiders[trie树优化dp]
官方题解 题意:给数列a[],选择尽量多的数满足任意两个异或起来<=k 1625D - Binary Spiders 思路:首先,将数列排序得到,然后升序取得的值的任意两个最小值为相邻两个异或的 ...
- 《C Primer Plus》第六版笔记--1~3章
目录 第一章 初识C语言 1 使用C语言的7个步骤 1.1 定义程序目标 1.2 设计程序(功能实现) 1.3 编写代码 1.4 编译 1.5 运行程序 1.6 测试和调试程序 1.7 维护和修改代码 ...
- net core天马行空系列-微服务篇:全声明式http客户端feign快速接入微服务中心nacos
1.前言 hi,大家好,我是三合,距离上一篇博客已经过去了整整两年,这两年里,博主通关了<人生>这个游戏里的两大关卡,买房和结婚.最近闲了下来,那么当然要继续写博客了,今天这篇博客的主要内 ...
- 计算机网络 - HTTP和HTTPS的区别
计算机网络 - HTTP和HTTPS的区别 http所有传输的内容都是明文,并且客户端和服务器端都无法验证对方的身份. https具有安全性的ssl加密传输协议,加密采用对称加密. https协议需要 ...
- C#项目中常见的目录和文件
本文迁移自Panda666原博客,原发布时间:2021年4月17日. Bin 目录 bin是英文binary的缩写, 字面意思是二进制,意指用来存放编译后的结果.C#/VB编译器编译后的程序二进制文件 ...