题目描述
给定两个正整数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<=10^6;
100%的数据中,a<=b<=10^12。
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define ll unsigned long long
using namespace std;
ll l,r;
ll a[40],cover[40],dp[40],countl[40],countr[40];
inline void Solve(ll num,ll *A)
{
ll len(0);ll bit=num;
while(num)
{
a[++len]=num%10;
num/=10;
}
for(ll i=len;i>=1;i--)
{
for(ll j=0;j<10;j++)
A[j]+=dp[i-1]*a[i];
for(ll j=0;j<a[i];j++)
A[j]+=cover[i-1];
bit-=a[i]*cover[i-1],
A[a[i]]+=bit+1;
A[0]-=cover[i-1];
}
}
int main()
{
ll i;
cover[0]=1;
for(ll i=1;i<=16;++i)
{
dp[i]=(dp[i-1]<<3)+(dp[i-1]<<1)+cover[i-1];
cover[i]=(cover[i-1]<<3)+(cover[i-1]<<1);
}
scanf("%d%d",&l,&r);
Solve(l-1,countl);
Solve(r,countr);
for(ll i=0;i<10;i++)
printf("%lld ",countr[i]-countl[i]);
return 0;
}