数码
时间限制:1秒
空间限制:32768K
给定两个整数 l 和 r ,对于所有满足1 ≤ l ≤ x ≤ r ≤ 10^9 的 x ,把 x 的所有约数全部写下来。对于每个写下来的数,只保留最高位的那个数码。求1~9每个数码出现的次数。
输入描述:
一行,两个整数 l 和 r (1 ≤ l ≤ r ≤ 10^9)。
输出描述:
输出9行。 第 i 行,输出数码 i 出现的次数。
输入例子:
1 4
输出例子:
4 2 1 1 0 0 0 0 0
#include <iostream>
#include <cstdio>
#include <string>
#include <cstring>
#include <algorithm>
#include <queue>
#include <vector>
#include <set>
#include <stack>
#include <map>
#include <climits>
using namespace std;
#define LL long long
const int INF = 0x3f3f3f3f;
LL a[10],b[10],cnt[10];
int x[100009];
void f(int l,int r)
{
memset(cnt,0,sizeof cnt);
char ch[15];
while(l<=r)
{
sprintf(ch,"%d",r);
int k=ch[0]-'0';
for(int i=1; ch[i]; i++) k=k*10;
if(k<l) k=l;
cnt[ch[0]-'0']+=r-k+1;
r=k-1;
}
}
void get(int k,LL a[])
{
for(int i=1; i<=100000; i++)
a[x[i]]+=k/i;
if(k<=100000)return;
int p=k;
for(int i=1;; i++)
{
int kk=k/(i+1);
kk++;
if(kk<=100000) kk=100001;
f(kk,p);
for(int j=1; j<=9; j++) a[j]+=cnt[j]*i;
p=k/(i+1);
if(p<=100000) break;
}
}
int main()
{
for(int i=1; i<=9; i++)
for(int j=1; j<=10000; j*=10)
for(int k=0; k<j; k++) x[i*j+k]=i;
x[100000]=1;
int l,r;
while(~scanf("%d%d",&l,&r))
{
get(r,b);
get(l-1,a);
for(int i=1; i<=9; i++) printf("%lld\n",b[i]-a[i]);
}
return 0;
}