bzoj1833
hh
1 #include<cstdio> 2 #include<cstring> 3 #include<ctime> 4 #include<cmath> 5 #include<algorithm> 6 #include<cstdlib> 7 #include<iostream> 8 #define rep(i,l,r) for(int i=l;i<r;i++) 9 #define clr(a,x) memset(a,x,sizeof(a)) 10 typedef long long ll; 11 using namespace std; 12 const int maxl=15,maxs=10; 13 int a[maxl]; 14 ll l,r,ans[maxs][2],d[maxl][maxs][maxs]; 15 void init(){ 16 ll power=1; 17 rep(i,0,maxs) d[1][i][i]=1; 18 rep(i,2,maxl){ 19 power*=10ll; 20 rep(j,0,maxs){ 21 d[i][j][j]+=power; 22 rep(k,0,maxs) 23 rep(l,0,maxs) 24 d[i][j][l]+=d[i-1][k][l]; 25 } 26 } 27 } 28 int length(ll x){ 29 clr(a,0); 30 int ans=0; 31 if(!x) return a[0]=0; 32 for(;x;a[++ans]=x%10,x/=10); 33 return ans; 34 } 35 void work(ll x,int p){ 36 int len=length(x); 37 ll cnt=1,power=1; 38 rep(i,1,len+1){ 39 ans[a[i]][p]+=cnt; 40 cnt+=power*a[i]; 41 power*=10LL; 42 } 43 rep(i,1,len){ 44 rep(j,1,maxs) 45 rep(k,0,maxs) ans[k][p]+=d[i][j][k]; 46 } 47 for(int i=len;i;i--){ 48 rep(j,0,a[i]){ 49 if(j==0&&i==len) continue; 50 rep(k,0,maxs) ans[k][p]+=d[i][j][k]; 51 } 52 } 53 } 54 int main(){ 55 //freopen("test.in","r",stdin); 56 //freopen("my.out","w",stdout); 57 init(); 58 scanf("%lld%lld",&l,&r); 59 work(l-1,0);work(r,1); 60 rep(i,0,maxs){ 61 printf("%lld",ans[i][1]-ans[i][0]); 62 if(i!=9) putchar(' '); 63 } 64 return 0; 65 }
1833: [ZJOI2010]count 数字计数
Time Limit: 3 Sec Memory Limit: 64 MBSubmit: 2005 Solved: 884
[Submit][Status][Discuss]
Description
给定两个正整数a和b,求在[a,b]中的所有整数中,每个数码(digit)各出现了多少次。
Input
输入文件中仅包含一行两个整数a、b,含义如上所述。
Output
输出文件中包含一行10个整数,分别表示0-9在[a,b]中出现了多少次。
Sample Input
1 99
Sample Output
9 20 20 20 20 20 20 20 20 20
HINT
30%的数据中,a<=b<=10^6;
100%的数据中,a<=b<=10^12。