[BZOJ1833] [ZJOI2010]count 数字计数

[ZJOI2010]count 数字计数

Description
ab[a,b](digit)
Input
ab
Output
1009[a,b]
Sample Input
199
Sample Output
9202020202020202020
HINT
30%的数据中, a<=b<=106
100%的数据中, a<=b<=1012

Solution :
dp[i][less]i0 9 ,我们先暴力枚举第一个非零位,然后dfs。

Code :

/************************************************************************* > File Name: bzoj1833.cpp > Author: Archer ************************************************************************/

#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/hash_policy.hpp>
using namespace std;

const int N = 22;
typedef long long ll;
#define MS(_) memset(_, 0xff, sizeof(_))
struct info{
    ll ans[N], cnt;
    info() {memset(ans, 0, sizeof(ans)); cnt = 0;}
}dp[N][2];
char str[N];
int vis[N][2];
ll L, R;
info operator +(const info &x, const info &y){
    info z; for (int i = 0; i <= N; i++) z.ans[i] = x.ans[i] + y.ans[i]; return z;
}
inline info dfs(int dep, int less){
    info ret, pack;
    if (~vis[dep][less]) { vis[dep][less] = 1; return dp[dep][less]; }
    vis[dep][less] = 1;
    if (dep >= strlen(str)){ ret.cnt = 1; dp[dep][less] = ret; return ret; }
    for (int i = 0; i <= 9; i++)
        if (less || i <= str[dep] - '0'){
            pack = dfs(dep + 1, (less || i < str[dep] - '0') ? 1 : 0);
            ret = ret + pack; ret.ans[i] += pack.cnt; 
        }
    return dp[dep][less] = ret;
}
int main(){
    scanf("%lld%lld", &L, &R); L--; MS(vis);

    sprintf(str, "%lld", L); info Lans, pack; 
    for (int i = 0; i < strlen(str); i++)
        for (int j = 1; j <= (i == 0 ? str[0]-'0' : 9); j++){
            info pack = dfs(i + 1, (i == 0 && j == str[0] - '0') ? 0 : 1);
            Lans = Lans + pack; Lans.ans[j] += pack.cnt;
        }
    sprintf(str, "%lld", R); info Rans; MS(vis);
    for (int i = 0; i < strlen(str); i++)
        for (int j = 1; j <= (i == 0 ? str[0]-'0' : 9); j++){
            info pack = dfs(i + 1, (i == 0 && j == str[0] - '0') ? 0 : 1);
            Rans = Rans + pack; Rans.ans[j] += pack.cnt;
        }
    for (int i = 0; i < 9; i++) printf("%lld ", Rans.ans[i] - Lans.ans[i]); 
    printf("%lld\n", Rans.ans[9] - Lans.ans[9]);
    return 0;
}

你可能感兴趣的:([BZOJ1833] [ZJOI2010]count 数字计数)