【BZOJ1833】【ZJOI2010】数字计数(数位DP)

#include<bits/stdc++.h>
#define ll long long
#define N 17
using namespace std;
ll a,b,num[N],s[N],f[N],ans[10][2];
//1~9在0~9中出现1次,0~99中出现20次,0~999中出现300次,0~9999中出现4000次...<—f[i] 
//s[i]=(10^i-1)-0+1=10^i; 
inline void dp(ll x,int st){ 
	register int i,j;
	ll tot=0,w=x,t;
	while(w) num[++tot]=w%10,w/=10;
	for(i=tot;i>=1;i--){
		//第i位选0 ~ num[i]-1,后面随便填
		for(j=0; j<=9; ans[j++][st]+=f[i-1]*num[i]); 
		for(j=0; j<num[i]; ans[j++][st]+=s[i-1]);
		//第i位选num[i]
		for(j=i-1,t=0;j>=1;j--) (t*=10)+=num[j]; 
		ans[num[i]][st]+=t+1;
		//处理前导零 
		ans[0][st]-=s[i-1];
	}
}
int main() {
	register int i;
	cin>>a>>b;
	s[0]=1;
	for(i=1;i<N;i++) 
		f[i]=f[i-1]*10+s[i-1],s[i]=s[i-1]*10;
	dp(b,0),dp(a-1,1);
	for(i=0;i<=9;i++)
		printf("%lld ",ans[i][0]-ans[i][1]);
	return 0;
}

  

posted @ 2020-07-18 21:24  Mistletoes  阅读(130)  评论(0编辑  收藏  举报