题目描述
给定两个正整数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时,_