给定两个整数 l 和 r ,对于所有满足1 ≤ l ≤ x ≤ r ≤ 10^9 的 x ,把 x 的所有约数全部写下来。对于每个写下来的数,只保留最高位的那个数码。求1~9每个数码出现的次数。
数据范围:1e9
$$我们发现21/6=3, 21/3=7,这说明1 到 21中能整除6,7的有三个,我们可以直接看8$$
$$我们发现21/8=2, 21/10=2,这说明1到21中能整除8,9,10的有2个,我们可以直接看11$$
$$我们发现21/11=1, 21/1=21,这说明1到21中能整除11到21的只有1个$$
$$这样我们就可以发现,一个数字被分成了一块一块的,而块的大小是(n/n/i - i + 1),注意这里是整除$$
$$所以我们可以枚举每一个最高位的数p,枚举p * 10,p * 10 * 10 … r$$
$$计算出当前块有多少个能整除$$
$$区间限定的话就可以用前缀和的思想解决cal(r) - cal(l-1)就是答案$$
#include <bits/stdc++.h>
using namespace std;
const int N = 1e9 + 10;
typedef long long ll;
ll l, r;
ll p;
ll get(ll x)
{
ll res = x / p;
for(ll st = p * 10, ed = min(p*10 + 9, x); st <= x; st *= 10, ed = ed * 10 + 9)
{
ll lim = min(ed, x);
for(ll i = st, R = 0; i <= lim; )
{
ll t = x / i;
R = min(x / t, lim);
res += (R - i + 1) * t;
i = R + 1;
}
}
return res;
}
int main()
{
scanf("%lld %lld", &l, &r);
for(p = 1; p <= 9; p ++)
{
cout << get(r) - get(l - 1) << endl;
}
}