【BZOJ1833】【ZJOI2010】count 数字计数 (数位DP)
2018-02-19 22:45
375 查看
Description
给定a,ba,b,求出aa到bb之间所有的整数中所有的数字出现个数和。Solution
设fi,j,kfi,j,k为以jj开头、长度为ii的所有数(允许前导0)中数字kk的出现次数。预处理出fi,j,kfi,j,k,然后数位DP即可。
感觉做复杂了点吧 ,应该有更简单的做法。
Source
/**************************** * Au: Hany01 * Prob: [BZOJ1833][ZJOI2010] count 数字计数 * Date: Feb 19th, 2018 * Email: hany01@foxmail.com ****************************/ #include<bits/stdc++.h> using namespace std; typedef long long LL; typedef pair<int, int> PII; typedef vector<int> VI; #define Rep(i , j) for (register int i = 0 , i##_end_ = j; i < i##_end_ ; ++ i) #define For(i , j , k) for (register int i = (j) , i##_end_ = (k) ; i <= i##_end_ ; ++ i) #define Fordown(i , j , k) for (register int i = (j) , i##_end_ = (k) ; i >= i##_end_ ; -- i) #define Set(a , b) memset(a , b , sizeof(a)) #define SZ(a) ((int)(a.size())) #define ALL(a) a.begin(), a.end() #define pb(a) push_back(a) #define mp(a, b) make_pair(a, b) #define INF (0x3f3f3f3f) #define INF1 (2139062143) #define Mod (1000000007) #define y1 wozenmezhemecaia #ifdef hany01 #define debug(...) fprintf(stderr , __VA_ARGS__) #else #define debug(...) #endif inline void File() { #ifdef hany01 freopen("bzoj1833.in" , "r" , stdin); freopen("bzoj1833.out" , "w" , stdout); #endif } template<typename T> inline bool chkmax(T &a, T b) { return a < b ? a = b, 1 : 0; } template<typename T> inline bool chkmin(T &a, T b) { return b < a ? a = b, 1 : 0; } inline LL read() { register char c_; register LL _ , __; for (_ = 0 , __ = 1 , c_ = getchar() ; !isdigit(c_) ; c_ = getchar()) if (c_ == '-') __ = -1; for ( ; isdigit(c_) ; c_ = getchar()) _ = (_ << 1) + (_ << 3) + (c_ ^ 48); return _ * __; } struct List { LL a[10]; }null; List operator + (List L1, List L2) { List L3; Rep(i, 10) L3.a[i] = L1.a[i] + L2.a[i]; return L3; } int T, a[15], pos; LL n[2], Pow[15]; List cnt[2], dp[15], f[15][15]; inline void Init() { Pow[0] = 1; For(i, 1, 12) Pow[i] = Pow[i - 1] * 10ll; Rep(i, 10) f[1][i].a[i] = 1; For(i, 2, 12) Rep(j, 10) Rep(k, 10) f[i][k] = f[i][k] + f[i - 1][j], f[i][k].a[k] += Pow[i - 1]; } List dfs(int pos, int pre, int lmt) { if (!pos) return null; if (!lmt && pre >= 0 && dp[pos].a[0] > 0) return dp[pos]; List tmp = null; if (pre == -1) tmp = tmp + dfs(pos - 1, -1, 0); else { tmp = tmp + dfs(pos - 1, 0, lmt && !a[pos]); if (lmt && !a[pos]) tmp.a[0] += n[T] % Pow[pos - 1] + 1; else tmp.a[0] += Pow[pos - 1]; } For(i, 1, lmt ? a[pos] : 9) { tmp = tmp + dfs(pos - 1, i, lmt && a[pos] == i); if (lmt && i == a[pos]) tmp.a[i] += n[T] % Pow[pos - 1] + 1; else tmp.a[i] += Pow[pos - 1]; } if (!lmt && pre >= 0) dp[pos] = tmp; return tmp; } inline void Solve(int t) { LL tmp = n[t]; pos = 0; while (tmp) a[++ pos] = tmp % 10, tmp /= 10; cnt[t] = dfs(pos, -1, 1); } int main() { File(); Init(); n[0] = read() - 1, n[1] = read(); T = 0, Solve(0); T = 1, Solve(1); Rep(i, 9) printf("%lld ", cnt[1].a[i] - cnt[0].a[i]); printf("%lld\n", cnt[1].a[9] - cnt[0].a[9]); return 0; }
相关文章推荐
- Bzoj1833:[ZJOI2010]count 数字计数:数位dp
- [bzoj1833][ZJOI2010]count 数字计数——数位dp
- bzoj 1833: [ZJOI2010]count 数字计数【数位dp】
- BZOJ1833 [ZJOI2010]count 数字计数 【数学 Or 数位dp】
- BZOJ_1833_[ZJOI2010]count 数字计数_数位DP
- 【BZOJ】1833: [ZJOI2010]count 数字计数(数位dp)
- 【bzoj 1833】【codevs 1359】 [ZJOI2010]count 数字计数(数位dp)
- bzoj 1833 [ZJOI2010]count 数字计数(数位DP)
- BZOJ 1833: [ZJOI2010]count 数字计数 [数位DP]
- BZOJ-1833 [ZJOI2010]count 数字计数 数位DP
- 【BZOJ 1833】【ZJOI 2010】[数位DP]count 数字计数
- 【bzoj1833】[ZJOI2010]count 数字计数 数位DP
- [BZOJ 1833] [ZJOI2010] count 数字计数 【数位DP】
- [BZOJ1833] [ZJOI2010]count 数字计数 && 数位DP
- bzoj 1833: [ZJOI2010]count 数字计数(数位dp)
- [bzoj 1833] [ZJOI2010]count 数字计数:数位DP
- BZOJ 1833 [ZJOI2010]count 数字计数(数位dp)
- [省选前题目整理][BZOJ 1833][ZJOI 2010]count 数字计数(数位DP)
- bzoj1833: [ZJOI2010]count 数字计数(数位dp)
- [BZOJ1833][ZJOI2010]count 数字计数(数位dp)