题解 P4999 【烦人的数学作业】

数位 dp。

dpq,ii{0,1,2,3,4,5,6,7,8,9})为 1qi 出现的次数,1q 的数字和显然就是 dpq,0×0+dpq,1×1++dpq,i×i+dpq,9×9

所以我们只需要求出 1qi 出现的次数就能解决这个问题了。

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

这该怎么办呢?

有前导零的式子很容易推出。有 q 位数字,i 数码的出现次数对于 x{ssN,10qs10q+1}f(q,i) 的数量都是相等的(设 f(q,i)q 位数 i 数码的出现次数)。

具体求法罢,是:
{f(q,i)=0q=0f(q,i)=10f(q1)+10q1q>0

我们考虑减去多余的 0

我们先设数字为 A1A2A3An¯

我们首先考虑求 A1000¯,将 A1000¯ 分割为区间 [0000,1000),[1000,2000),,[(A11)000¯,A1000¯),所以答案就为 10n1A1,注意 <A1 的每个数还出现了 10n1 次,所以要加上。

首位 A1 出现了 A2A3An¯+1 次,答案还要加上 A2A3An¯+1

当然还需要处理前导 0,用排列组合算一下会知道 iq 个前导零的数量就是 10qq{ssN,0si1}),把它们加起来会发现一共出现了 10i1+10i2+...10=k=0i110k) 次,减一下即可。

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 出现的次数

posted @   yspm  阅读(208)  评论(1编辑  收藏  举报
编辑推荐:
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
😅​
点击右上角即可分享
微信分享提示