数位DP
数位DP
统计[a,b]之间每个数出现多少次。
#include <bits/stdc++.h>
using namespace std;
#define LL long long
LL ans1[15];
LL ans2[15];
//dp[i]位数为i,某数字总共出现次数
//mi:10的幂
LL dp[15], mi[15];
void solve(LL n, LL *res)
{
int num[15];
int cnt = 0;
LL tmp = n;
while (n)
num[++cnt] = n % 10,
n /= 10;
for (int i = cnt; i >= 1; --i)
{
//统计当前位置后面的所有(任意取)
for (int j = 0; j < 10; ++j)
res[j] += dp[i - 1] * num[i];
//统计当前位的
for (int j = 0; j < num[i]; ++j)
res[j] += mi[i - 1];
//还剩下多少数
tmp -= num[i] * mi[i - 1];
//当前位固定,剩下可以提供次数
res[num[i]] += tmp + 1;
}
//去掉前导0
for (int i = cnt; i >= 1; --i)
res[0] -= mi[i - 1];
}
int main()
{
LL a, b;
cin >> a >> b;
mi[0] = 1LL;
for (int i = 1; i <= 13; ++i)
{
dp[i] = dp[i - 1] * 10 + mi[i - 1];
mi[i] = mi[i - 1] * 10;
}
solve(a - 1, ans1);
solve(b, ans2);
for (int i = 0; i < 10; ++i)
cout << ans2[i] - ans1[i] << ' ';
return 0;
}