BZOJ 1833 count 数字计数

Posted on 2016-12-26 09:33  ziliuziliu  阅读(141)  评论(0编辑  收藏  举报

sb数位dp.

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
long long a,b,dp[15][10],tab[15],ans[10],bit[15],ret=0;
void get_table()
{
    tab[0]=1;
    for (long long i=1;i<=13;i++) tab[i]=tab[i-1]*10;
    for (long long i=0;i<=9;i++) dp[1][i]=1;
    for (long long i=2;i<=13;i++)    
        for (long long j=0;j<=9;j++)
            dp[i][j]=dp[i-1][j]*10+tab[i-1];
}
void get_bit(long long x)
{
    ret=0;
    while (x) {bit[++ret]=x%10;x/=10;}
}
void work(long long x,long long val)
{
    if (!x) return;
    get_bit(x);
    for (long long i=1;i<=ret-1;i++)
        for (long long j=1;j<=9;j++)
        {
            ans[j]+=tab[i-1]*val;
            for (long long k=0;k<=9;k++) ans[k]+=dp[i-1][k]*val;
        }
    for (long long i=ret;i>=1;i--)
    {
        for (long long j=(i==ret);j<bit[i];j++)
        {
            ans[j]+=tab[i-1]*val;
            for (long long k=0;k<=9;k++) ans[k]+=dp[i-1][k]*val;
        }
        ans[bit[i]]+=(x-bit[i]*tab[i-1]+1)*val;x%=tab[i-1];
    }
}
int main()
{
    scanf("%lld%lld",&a,&b);get_table();
    work(b,1);work(a-1,-1);
    for (long long i=0;i<=8;i++) printf("%lld ",ans[i]);printf("%lld\n",ans[9]);
    return 0;
}