题目链接
思路:显然暴力的做法是for i:1-r 看在[l,r]内有多少个数是是i的倍数。

for(int i=1;i<=r;i++){
    ans[get(i)]+=r/i-(l-1)/i;//get()为获取i的第一个数码
}

怎么优化呢?
观察暴力的式子我们可以发现:r/i和(l-1)/i是两个除法的式子。显然是可以除法分块的。
这样就可以把正贡献和负贡献分开用除法分块计算。
统计答案的时候模拟一下即可。

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N = 2e5 + 10;
#define fi first
#define se second
#define pb push_back
LL cnt[55],fac[13];
void add(int l,int r,int x,int y){
  int xx=0,yy=0,g1=0,g2=0,R=r,L=l;//cout<<l<<' '<<r<<endl;
  while(l){
    g1=l%10;
    l/=10;
    xx++;
  }
  while(r){
    g2=r%10;
    r/=10;
    yy++;
  }
  if(xx==yy && g1==g2){
    cnt[g1]+=1ll*y*x*(R-L+1);
  }else if(xx==yy && g1!=g2){
    for(int i=g1+1;i<g2;i++){
      cnt[i]+=1ll*y*x*fac[xx-1];
    }
    cnt[g1]+=1ll*y*x*(1ll*(g1+1)*fac[xx-1]-L);
    cnt[g2]+=1ll*y*x*(R-1ll*g2*fac[yy-1]+1);
  }else{
    for(int i=xx;i<yy-1;i++){
      for(int j=1;j<=9;j++){
        cnt[j]+=1ll*y*x*fac[i];
      }
    }
    for(int i=g1+1;i<=9;i++){
      cnt[i]+=1ll*y*x*fac[xx-1];
    }
    for(int i=1;i<g2;i++){
      cnt[i]+=1ll*y*x*fac[yy-1];
    }
    cnt[g1]+=1ll*y*x*(1ll*(g1+1)*fac[xx-1]-L);
    cnt[g2]+=1ll*y*x*(R-1ll*g2*fac[yy-1]+1);
  }
}
int l,r;
int main() {
  ios::sync_with_stdio(false);
  fac[0]=1;
  for(int i=1;i<=10;i++)fac[i]=fac[i-1]*10;
  cin>>l>>r;
  l--;
  for(int i=1,j;i<=r;i=j+1){
    j=r/(r/i);
    add(i,j,r/i,1);
  }
  for(int i=1,j;i<=l;i=j+1){
    j=l/(l/i);
    add(i,j,l/i,-1);
  }
  for(int i=1;i<=9;i++)cout<<cnt[i]<<'\n';
  return 0;
}