设f[i][j][k]表示长度为i,开头为j的数中k的个数
分开统计答案,对于位数小于当前数的直接全部加上,剩余的拆分统计
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#define LL long long
using namespace std;
const int maxn=51;
LL a,b,ret[maxn],f[maxn][maxn][maxn],bin[maxn];
int d[maxn];
LL solve(LL x,int flag){
int dnum=0; LL tmpn=x;
memset(d,0,sizeof(d));
while(x){d[++dnum]=x%10;x/=10;}
for (int i=1;i<=dnum-1;++i)
for (int j=1;j<=9;++j)
for (int k=0;k<=9;++k)
ret[k]+=(f[i][j][k]*flag);
int tmp=dnum;
while (tmp){
for (int i=0;i<d[tmp];++i){
if (!i&&tmp==dnum) continue;
for (int j=0;j<=9;++j)
ret[j]+=(f[tmp][i][j]*flag);
}
ret[d[tmp]]+=(tmpn%bin[tmp]+1)*flag;
tmp--;
}
}
int main(){
bin[1]=1;
for (int i=2;i<=13;++i) bin[i]=bin[i-1]*10;
for (int i=0;i<=9;++i) f[1][i][i]=1;
for (int i=2;i<=13;++i)
for (int j=0;j<=9;++j)
for (int k=0;k<=9;++k){
for (int z=0;z<=9;++z)
f[i][j][z]+=f[i-1][k][z];
f[i][k][k]+=bin[i-1];
}
scanf("%lld%lld",&a,&b);
solve(b,1); solve(a-1,-1);
for (int i=0;i<=8;++i) printf("%lld ",ret[i]);
printf("%lld\n",ret[9]);
}