题目要求区间[l,r]的每个数的因数,然后计算每个因数最高的数是出现多少次?
那咋写呢?考虑朴素算法..就是枚举[l,r]每个数的因子再对最高位进行统计..但是这样算法的复杂度就到了大于O(r-l)的级别.具体我也不会算.这样肯定不行,考虑优化.怎么优化呢?
首先求[l,r]中区间每个因数最高的数是出现多少次,是不是就等同于 求[1,r]中每个因数最高的数出现多少次-求[1,l-1]中每个因数最高的数出现多少次?那么我们来枚举一个因式从而确定另外一个因式的多少,保证在因式的积在l~r的范围就好了吧?
枚举因数肯定是枚举到根号x就好了...因为之前的都算过了.

#include<bits/stdc++.h>
#define ios ios_base::sync_with_stdio(0),cin.tie(0),cout.tie(0)
#define pb push_back
#define inf 132913423039
typedef long long ll;
const ll mod=1e9+7;
const ll N=2e5+5;
const ll M=10+5;
const double eps=1e-7;
using namespace std;
ll gcd(ll a,ll b) {return b==0?a:gcd(b,a%b);}
ll lcm(ll a,ll b) { return a*b/gcd(a,b);    }
ll qp(ll a,ll b, ll p){ll ans = 1;while(b){if(b&1){ans = (ans*a)%p;--b;}a = (a*a)%p;b >>= 1;}return ans%p;}
ll Inv(ll x)          { return qp(x,mod-2,mod);}
ll C(ll n,ll m){if (m>n) return 0;ll ans = 1;for (int i = 1; i <= m; ++i) ans=ans*Inv(i)%mod*(n-i+1)%mod;return ans%mod;}
ll A(ll n,ll m,ll mod){ll sum=1; for(int i=n;i>=n-m+1;i--) sum=(sum*i)%mod; return sum%mod;}
ll lowbit(ll x) {return x&(-x);}
ll c[N],sum1[N],sum2[N],a[N],lsh[N],n,m;
void add1(ll i,ll k){ while(i<=n) {c[i]+=k;i+=lowbit(i);}}//预处理ai单点修改 区间查询***预处理a[i]-a[i-1]区间修改单点查询
ll  Sum1(ll i) {ll res=0; while(i>0) res+=c[i],i-=lowbit(i);return res;}//预处理ai单点修改 区间查询***预处理a[i]-a[i-1]区间修改单点查询
void add2(ll i,ll k){ ll x=i;while(i<=n) {sum1[i]+=k;sum2[i]+=k*(x-1);i+=lowbit(i);}}//区间修改,区间查询
ll  Sum2(ll i) {ll res=0,x=i;while(i>0){ res+= x * sum1[i]-sum2[i]; i -= lowbit(i);}return res;}//区间修改,区间查询
void ls(){ll cnt; for(ll i=1;i<=n;i++) lsh[i]=a[i]; sort(lsh+1,lsh+n+1);cnt = unique(lsh+1,lsh+n+1)-lsh-1; for(int i=1;i<=n;i++)a[i]=lower_bound(lsh+1,lsh+cnt+1,a[i])-lsh;}
ll le[M],ri[M];
ll cnt(ll x) {ll ans; while(x) {ans=x%10;x/=10;}return ans;}//统计最高位是多少.
void getans1(ll x)
{
    for(ll i=1;i*i<=x;i++)//枚举一个因数
    {
         ll top=x/i,dep=i+1;//上线和下限.
        /*
        枚举到的最大值是x/i吧.
        枚举的最小值肯定是i+1.要求不重复啊!
        那么枚举的范围是不是就是x/i-i了呢?
        但是这个题目不是问你总数有多少啊!而是问你以某某开头的数有多少.那么我们另外一个因数可以采取枚举开头统计个数
        */
        for(ll j=1;j<=x;j=j*10)//枚举现在是几位数
        {
            for(ll k=1;k<10;k++)//枚举这位数下以k开头的数最大和最小是多少.
            {
               /*这里统计的时候要注意下最大值和最小值*/
               //现在这个数的最小值是j*k,那么它的最大值就是(j+1)*k-1
               ll mi=max(dep,j*k);
               ll mx=min(top,(k+1)*j-1);
               if(mi<=mx)//假如我枚举的最小值大于最大值那么不符合条件的
               {
                   le[k]+=mx-mi+1;//另外一个因数个数
               }
            }
        }
        le[cnt(i)]+=x/i-i+1;//第一个因数个数
    }
}
void getans2(ll x)
{
    for(ll i=1;i*i<=x;i++)//枚举一个因数
    {
         ll top=x/i,dep=i+1;//上线和下限.
        /*
        枚举到的最大值是x/i吧.
        枚举的最小值肯定是i+1.要求不重复啊!
        那么枚举的范围是不是就是x/i-i了呢?
        但是这个题目不是问你总数有多少啊!而是问你以某某开头的数有多少.那么我们另外一个因数可以采取枚举开头统计个数
        */
        for(ll j=1;j<=x;j=j*10)//枚举现在是几位数
        {
            for(ll k=1;k<10;k++)//枚举这位数下以k开头的数最大和最小是多少.
            {
               /*这里统计的时候要注意下最大值和最小值*/
               //现在这个数的最小值是j*k,那么它的最大值就是(j+1)*k-1
               ll mi=max(dep,j*k);
               ll mx=min(top,(k+1)*j-1);
               if(mi<=mx)//假如我枚举的最小值大于最大值那么不符合条件的
               {
                   ri[k]+=mx-mi+1;//另外一个因数个数
               }
            }
        }
        ri[cnt(i)]+=x/i-i+1;//第一个因数个数
    }
}
signed main()
{
    ios;
    ll l,r;
    cin>>l>>r;
    getans1(r);getans2(l-1);
    for(ll i=1;i<=9;i++) cout<<le[i]-ri[i]<<endl;
    return 0;
}
//因数i和i的那种情况只能计算一种.