【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; }