题目:
给定两个整数(l)和(r),对于任意(x),满足(lleq xleq r),把(x)所有约数写下来。
对于每个写下来的数,只保留最高位的那个数码。求([1,9])中每个数码出现的次数.
(1 leq l leq r leq 10^9)
题解:
转化成统计贡献。
考虑每个数落在区间内多少次。
将每种数码分开考虑即可。
由于每种数码的数的区间不是连续的,所以枚举一下即可。
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long ll;
inline void read(int &x){
x=0;char ch;bool flag = false;
while(ch=getchar(),ch<'!');if(ch == '-') ch=getchar(),flag = true;
while(x=10*x+ch-'0',ch=getchar(),ch>'!');if(flag) x=-x;
}
#define rg register int
#define rep(i,a,b) for(rg i=(a);i<=(b);++i)
#define pre(i,a,b) for(rg i=(a);i>=(b);--i)
inline ll solve(int n,int l,int r){
ll ret = 0;
for(rg i = l,j = i;i <= r;i = j+1){
j = n/(n/i);j = min(j,r);
ret += 1LL*(j-i+1)*(n/i);
}return ret;
}
inline ll query(int n,int k){
ll ans = 0,x = k,y = 1;
while(x <= n){
ans += solve(n,x,min(x+y-1,1LL*n));
x *= 10;y *= 10;
}return ans;
}
int main(){
int l,r;read(l);read(r);
rep(i,1,9){
printf("%lld
",query(r,i) - query(l-1,i));
}
return 0;
}