//https://www.luogu.com.cn/problem/P2602
#include <bits/stdc++.h>
#define ll long long
#define all(a) (a).begin(), (a).end()
#define IOS ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
using namespace std;
const int inf = 0x3f3f3f3f;
const ll INF = 0x3f3f3f3f3f3f3f3f;
const int N = 1e5 + 10;
int num[20];
ll pow10[20], now[20];
ll f[20];
ll dfs(int pos, int dig, bool lead, bool limit)
{
if(pos == 0) return 0;
if(!lead && !limit && f[pos] != -1) return f[pos];
ll ans = 0;
int up = limit ? num[pos] : 9;
for(int i = 0; i <= up; i++)
{
if(lead && i == 0)
ans += dfs(pos - 1, dig, lead && i == 0, limit && i == up);
else if(i == dig && limit && i == up)
ans += now[pos - 1] + 1 + dfs(pos - 1, dig, lead && i == 0, limit && i == up);
else if(i == dig)
ans += pow10[pos - 1] + dfs(pos - 1, dig, lead && i == 0, limit && i == up);
else
ans += dfs(pos - 1, dig, lead && i == 0, limit && i == up);
}
if(!lead && !limit) f[pos] = ans;
return ans;
}
ll run(ll x, int dig)
{
int len = 0;
while(x)
{
num[++len] = x % 10;
x /= 10;
now[len] = now[len - 1] + pow10[len - 1] * num[len];
}
memset(f, -1, sizeof f);
return dfs(len, dig, true, true);
}
void solve()
{
ll l, r;
cin >> l >> r;
pow10[0] = 1;
for(int i = 1; i <= 15; i++) pow10[i] = pow10[i - 1] * 10;
for(int i = 0; i <= 9; i++) cout << run(r, i) - run(l - 1, i) << " \n"[i == 9];
}
signed main()
{
IOS;
int t = 1;
// cin >> t;
while (t--)
solve();
return 0;
}
数字计数(数位DP板子题)
于 2023-01-05 11:40:18 首次发布
![](https://img-home.csdnimg.cn/images/20240711042549.png)