数位DP

#include<bits/stdc++.h>
using namespace std;

#define V vector
#define pii pair<int,int>
using ll = long long;
const int inf = 0x3f3f3f3f;
const int N = 1e5 + 10;

ll ans[10],f[20];
int c[20];
inline ll read()
{
    ll res = 0, a = 1;
    char c  = getchar();
    while (c < '0' || c>'9')
    {
        if(c == '-')a = -1;
        c = getchar();
    }
    while (c >= '0' && c <= '9')
    {
        res = res * 10 + c - '0';
        c = getchar();
    }
    return res * a;
}


inline void clac(ll n, ll xs)
{
    int m = 0;
    while (n)
    {
        c[++m] = n % 10;
        n /= 10;
    }
    for (int i = 1, j = m; i < j; i++, j--)
    {
        swap(c[i], c[j]);
    }
    //小于n的所有数字贡献
    for (int i = 1; i <= m; i++)
    {
        //前i-1个相等
        for (int j = 1; j < i; j++)
            ans[c[j]] += (ll)c[i] * f[m - i] * xs;
        //算i位出现1—(c[i]-1) 个数
        for (int j = 1; j < c[i]; j++)
            ans[j] += xs * f[m - i];
        //i位置出现0个数——因为只考虑<n的数字,所以c[i]>0
        if (i != 1 && c[i])
            ans[0] += xs * f[m - i];
        //大于i的位置
        if (i != m)
        {
            //剩下m-i位置中的一位  
            for (int j = 1; j < 10; j++)
                ans[j] += xs * f[m - i - 1] * ((ll)m - i) * c[i];
            if (i != 1)
                ans[0] += xs * f[m - i - 1] * ((ll)m - i) * c[i];
        }
        //首位处理0个数
        if (i == 1)
        {
            if (m >= 2)
            {
                //i>1上位置的0 除去本身位置的和首位 还有m-2个位置 —>f[m-2]
                //共有m-1个位置
                ans[0] += xs * ((ll)c[1] - 1) * ((ll)m - 1) * f[m - 2];
            }
            //
            for (int j = 2; j < m; j++)
            {
                ans[0] += xs * 9 * (ll)(m - j) * f[m - j - 1];
            }
        }
    }
    //加上本身
    for (int i = 1; i <= m; i++)
        ans[c[i]] += xs;
}
int main()
{
    ll l, r;
    f[0] = 1;
    for (int i = 1; i <= 17; i++)
    {
        f[i] = f[i - 1] * 10;
    }
    cin >> l >> r;
    clac(r, 1);
    clac(l - 1, -1);

    for (int i = 0; i <= 9; i++)
        cout << ans[i] << " ";
}

Last updated