【BZOJ 1833】【ZJOI 2010】[数位DP]count 数字计数
2017-03-13 15:32
477 查看
题目描述
给定两个正整数a和b,求在[a,b]中的所有整数中,每个数码各出现了多少次。题目分析
膜膜膜PoPoQQQ大爷。首先,我们可以把求[a,b]中间的数量改成[1,b]-[1,a-1]。
然后考虑怎么求[1,x]。
首先,对于位数小于x的数字因为每位数可以随便取,所以每一个数字出现次数是一样的(允许前导0)。我们不妨预处理gi表示位数为i时数字出现的次数,gi=gi−1×10+10i−1,因为对于数字的第i位有10种取法,相应的前i−1位就会被重复计算10次,而新增的第i位每一种数码又会出现10i−1次。然而累加时还需要考虑前导0,我们可以先枚举位数,对于0累加时,我们不考虑第i位为0:ans=gi−1×9;其他的就是ans=gi−1×9+10i−1。
现在考虑位数和x相同时怎么做,我们还是从高到低枚举每一位数,不妨设当前数为now,枚举的是第pos位,那么增量就是t=10pos−1。若now+t<=x时,因为最高位没有达到上限,因此前pos−1位可以随便取,产生的贡献是当前已确定的后几位数中的数码乘以10pos−1(出现次数),加上前pos−1位数不计前导0的gpos。
然后就完了,唯一需要注意的是因为枚举每一位数时都没有计算上限值,所以答案求出来是[1,x)于是我们还是要计算[1,r+1)−[1,l)的值。
代码
/************************************************************** Problem: 1833 User: szpszp Language: C++ Result: Accepted Time:4 ms Memory:1292 kb ****************************************************************/ #include<cstdio> #include<iostream> #include<cstring> #include<algorithm> #include<cmath> using namespace std; #define MAXN #define MAXM #define INF 0x3f3f3f3f typedef long long int LL; template<class T> void Read(T &x){ x=0;char c=getchar();bool flag=0; while(c<'0'||'9'<c){if(c=='-')flag=1;c=getchar();} while('0'<=c&&c<='9'){x=x*10+c-'0';c=getchar();} if(flag)x=-x; } LL g[20],powten[20]; int num[15]; int len; void getnum(LL x){ len=0; while(x)num[++len]=x%10,x/=10; } LL ans[10]; void Solve(LL x,LL flag){ getnum(x); for(int i=1;i<len;++i){ ans[0]+=g[i-1]*9*flag;//0不能放在末尾 for(int j=1;j<10;++j) ans[j]+=(g[i-1]*9+powten[i-1])*flag; } LL now=powten[len-1],t=now; int pos=len-1; while(now<x){ while(now+t<=x){ LL tmp=now/t; while(tmp)ans[tmp%10]+=t*flag,tmp/=10; for(int i=0;i<10;++i)ans[i]+=g[pos]*flag; now+=t; } t/=10,--pos; } } void init(){ memset(ans,0,sizeof(ans)); g[0]=0,powten[0]=1; for(LL i=1;i<15;++i){ powten[i]=powten[i-1]*10; g[i]=g[i-1]*10+powten[i-1]; } } int main(){ init(); LL l,r; Read(l),Read(r); Solve(r+1,1); Solve(l,-1); for(int i=0;i<9;++i) printf("%lld ",ans[i]); printf("%lld\n",ans[9]); }
相关文章推荐
- 【bzoj1833】[ZJOI2010]count 数字计数 数位DP
- [bzoj1833][ZJOI2010]count 数字计数——数位dp
- bzoj 1833 [ZJOI2010]count 数字计数(数位DP)
- BZOJ 1833: [ZJOI2010]count 数字计数 数位DP,处理前导0
- 【BZOJ1833】【ZJOI2010】count 数字计数 (数位DP)
- BZOJ 1833: [ZJOI2010]count 数字计数 [数位DP]
- BZOJ-1833 [ZJOI2010]count 数字计数 数位DP
- BZOJ1833 [ZJOI2010]count 数字计数 【数学 Or 数位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 ZJOI2010 count 数字计数 数位DP
- BZOJ_1833_[ZJOI2010]count 数字计数_数位DP
- [BZOJ 1833] [ZJOI2010] count 数字计数 【数位DP】
- [省选前题目整理][BZOJ 1833][ZJOI 2010]count 数字计数(数位DP)
- Bzoj1833:[ZJOI2010]count 数字计数:数位dp
- [BZOJ 1833][ZJOI 2010]count数字计数(数位DP)
- BZOJ 1833 ZJOI 2010 count 数字计数 数位DP