BZOJ1833 [ZJOI2010]count 数字计数 数学 Or 数位dp

Posted Mychael

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了BZOJ1833 [ZJOI2010]count 数字计数 数学 Or 数位dp相关的知识,希望对你有一定的参考价值。

题目

给定两个正整数a和b,求在[a,b]中的所有整数中,每个数码(digit)各出现了多少次。

输入格式

输入文件中仅包含一行两个整数a、b,含义如上所述。

输出格式

输出文件中包含一行10个整数,分别表示0-9在[a,b]中出现了多少次。

输入样例

1 99

输出样例

9 20 20 20 20 20 20 20 20 20

提示

30%的数据中,a<=b<=10^6;
100%的数据中,a<=b<=10^12。

题解

你以为我真的会写数位dp?

首先容斥一下,转化为求小于等于n的方案数

如果不考虑前缀0,那么就只需要递归处理不大于n所有数字出现的次数
考虑前缀0,我们再减去开头有若干个0的方案数

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#define LL long long int
#define Redge(u) for (int k = h[u],to; k; k = ed[k].nxt)
#define REP(i,n) for (int i = 1; i <= (n); i++)
#define BUG(s,n) for (int i = 1; i <= (n); i++) cout<<s[i]<<‘ ‘; puts("");
using namespace std;
const int maxn = 15,maxm = 100005,INF = 1000000000;
LL g[maxn],Pow[maxn];
void init(){
    Pow[0] = 1;
    for (int i = 1; i < maxn; i++) Pow[i] = Pow[i - 1] * 10;
    g[1] = 1;
    for (int i = 2; i < maxn; i++){
        g[i] = 10 * g[i - 1] + Pow[i - 1];
    }
}
struct node{
    LL t[10];
    node(){memset(t,0,sizeof(t));}
};
node cal(LL n,LL h,LL tmp){
    //cout << n << endl;
    node re,t;
    if (h == 1){
        for (int i = 0; i <= n; i++) re.t[i] = 1;
        return re;
    }
    for (int i = 0; i <= 9; i++){
        re.t[i] += (n / tmp) * g[h - 1];
        if (i < n / tmp) re.t[i] += Pow[h - 1];
    }
    re.t[n / tmp] += n - (n / tmp) * tmp + 1;
    t = cal(n % tmp,h - 1,tmp / 10);
    for (int i = 0; i <= 9; i++) re.t[i] += t.t[i];
    return re;
}
node solve(LL n){
    LL h = 1,tmp = 1;
    for (LL i = n; i / 10; i /= 10) h++,tmp *= 10;
    node re = cal(n,h,tmp);
    for (int i = 1; i < h; i++){
        re.t[0] -= Pow[h - i];
    }
    return re;
}
int main(){
    init();
    LL a,b;
    cin >> a >> b;
    node ansr = solve(b),ansl = solve(a - 1);
    for (int i = 0; i < 9; i++) printf("%lld ",ansr.t[i] - ansl.t[i]);
    printf("%lld",ansr.t[9] - ansl.t[9]);
    return 0;
}

以上是关于BZOJ1833 [ZJOI2010]count 数字计数 数学 Or 数位dp的主要内容,如果未能解决你的问题,请参考以下文章

bzoj 1833: [ZJOI2010]count 数字计数

bzoj 1833 [ZJOI2010]count 数字计数

bzoj1833 ZJOI2010—count 数字计数

BZOJ1833 [ZJOI2010] count

bzoj1833: [ZJOI2010]count 数字计数(数位DP+记忆化搜索)

BZOJ_1833_[ZJOI2010]count 数字计数_数位DP