感受
整数分块真香!
思路
一般询问区间[L, R]的问题要么直接处理,要么分成[1, R]-[1, L - 1]处理。
直接考虑第二种处理方法,怎么求[1,x]的答案呢?
比如我们想求解约数的最高位的那个数码为4的情形
- 4
- [40, 49]
- [400, 499]
...
有什么用呢?
如果一个约数为q,那么区间[1, n]中存在约数为q的有【n/q】(下取整)
是不是想到了,这不是就是傻×分块吗?
复杂度分析
枚举数码O(9)
- 枚举数码对应的区间
- 对于每一个区间,进行整数分块求解
总复杂度最坏为O(9 * 10 * sqrt(n))= O(1e6)
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 1e4 + 10;
ll l, r;
ll solve(ll n, ll i){
ll ans = 0; ans += n / i;
ll f = i * 10; ll top = i * 10 + 9; top = min(top, n);
ll num;
for(; f <= n; f *= 10, top = top * 10 + 9, top = min(top, n)){
for(ll L = f, R; L <= top; L = R + 1){
num = n / L;
R = n / num; R = min(top, R);
ans += num * (R - L + 1);
}
}
return ans;
}
int main(){
scanf("%lld%lld", &l, &r);
for(ll i = 1; i <= 9; i++){
printf("%lld\n", solve(r, i) - solve(l - 1, i));
}
return 0;
}



京公网安备 11010502036488号