P2602 [ZJOI2010]数字计数(非数位dp做法)

题目描述

给定两个正整数a和b,求在[a,b]中的所有整数中,每个数码(digit)各出现了多少次。

输入格式:

输入文件中仅包含一行两个整数a、b,含义如上所述。

输出格式:

输出文件中包含一行10个整数,分别表示0-9在[a,b]中出现了多少次。

输入输出样例

输入 #1

1 99

输出 #1

9 20 20 20 20 20 20 20 20 20

说明/提示

数据规模与约定

  • 对于 30% 的数据,保证 a ≤ b ≤ 106
  • 对于 100% 的数据,保证 1≤ a ≤ b ≤ 1012

思路

dalao们都用数位dp
本蒟蒻不会,果然我还是太菜了
想了个不是数位dp的做法

对于[l,r]区间的某个数出现次数,显然可以用[1,r]中这个数出现的次数减去[1,l-1]中这个数出现的次数(类似差分),所以问题就转化为了求[1,n]中某个数出现的次数(n∈N*)。

对于上述问题,用下面方法求解:

对于n的每一位从小到大遍历,固定该位为所要求次数的数(为了方便叙述,下文设为x),然后统计贡献值。

具体的,
对于n=6572,
设固定的位上的数为m,该位左边为l,右边为r;
例如,固定个位时 l=657,m=7,r=0(因为个位右边没有数)

显然l,m,r可用下式求得:

l=n/(p*10)
m=n/p%10
r=n%p

其中p为该位的权值(个位为1,十位为10,以此类推)

对于答案的累计,

固定的第k位为x,k位左边的数l的贡献加上右边的数r的贡献。
更具体的,对于n=6572的第二位

  • 若x<7 左边可以为 x_,1x_,2x_,…,64x_,_中的数可选0-9共十个,还有右边的贡献65x0至65x9共10个,对答案的贡献为(1+65)×10,即(l+1)×10;
  • 若x=7 左边可以为 x_,1x_,2x_,…,64x_,_中的数可选0-9共十个,还有右边的贡献65x0至65xr共r+1个,对答案的贡献为65×10+r+1,即l×10+r+1;
  • 若x<7 左边可以为 x_,1x_,2x_,…,64x_,_中的数可选0-9共十个,右边没有贡献,对答案的贡献为65×10,即l×10;

显然,

  • 对k=1时,_中不可选,可选数默认为1,即l×1;
  • 对k=3时,_中可选0-99共100个,即l×100;
  • 对k=4时,_
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值