题解:
很容易知道,每个数x的贡献为r/x,而且,许多相邻的数贡献是一样的。
比如:r=88,当首位为1时,x的可能取值为 { {1} , { [10,19) } }这两个可行区间。
x=1, ans+=88;
x=10, ans+=(88/10 = 8);
x=11, ans+=(88/11 = 8);
我们发现,10和11的贡献是相同的,当我们枚举到10的时候,得到的答案是8,此时只要88/8=11,代表一直到枚举到11,答案都是8,所以我们就可以直接跳到12,以此类推。。。
答案就是两个区间相减[1,r]-[1,l-1]。
#include <bits/stdc++.h> using namespace std; typedef long long ll; ll cal(ll n, ll k) { ll ans = n / k; for (ll l = k * 10, r = min(l + 9, n); l <= n; l *= 10, r = min(r * 10 + 9, n)) { for (ll i = l; i <= r;) { ll now = n / i; ll add = min(n / now, r); ans += now * (add - i + 1); i = add + 1; } } return ans; } int main() { ll x, y; cin >> x >> y; for (ll i = 1; i <= 9; i++) cout << cal(y, i) - cal(x - 1, i) << '\n'; return 0; }