每日一题 数码

链接戳这
题意:
求 l<=x<=r 中 x的所有约数的最高位出现的次数
思路:
一开始以为是通过枚举因子反着枚举,看了题解才发现是暴力枚举每个最高数位,然后枚举范围通过整除分块来做,复杂度是图片说明 然后呢,枚举最高位,整除分块的思想就马上体现了,由于是求l~r中的,那么数位dp中的思想就马上体现出来了,l~r就是等价于solve(r)-solve(l-1),如何写solve呢,solve函数的含义就是1~x中能被最高位i整除的最高位出现的个数,显而易见一个因数p能把1~x中数整除的个数是图片说明 ,那么n/p这个值会出现在一段l~r的区间,这个右区间就是图片说明 我们慢慢得跳即可。
代码:

#include<bits/stdc++.h>
using namespace std;
#define int long long 
int cnt[10];
int l,r;
int L(int x)
{
    int res=0;
    while(x)
    {
        x/=10;
        res++;
    }
    return res;
}
int maxp(int x)
{
    while(x)
    {
        if(x<10)
            return x;
        x/=10;
    }
    return -1;
}
int qmi(int a,int b)
{
    int res=1;
    while(b)
    {
        if(b&1) res=res*a;
        a=a*a;
        b>>=1;
    }
    return res;
}
int solve(int x,int v)//1~x满足条件的   1~1 10~19 100~199
{
    int res=0;
    for(int i=1;i<=x;i*=10)
    {
        int l=v*i;
        int r=min((v+1)*i-1,x);
        //cout<<l<<" "<<r<<endl;
        for(int j=l;j<=r;)
        {
            int xx=min(x/(x/j),r);
            //cout<<xx<<endl;
            res+=(xx-j+1)*(x/j);
            j=xx+1;
        }
    }
    return res;
}
signed main()
{
    cin >> l >> r;
    for(int i=1;i<=9;i++)
    cout<<solve(r,i)-solve(l-1,i)<<endl;

    return 0;
}
全部评论

相关推荐

allin实习的大白...:我把第二个项目发出来了,如果感兴趣可以去研究研究,欢迎交流。 https://gitee.com/jtyjtyjty333/ind-dist-ai-sec-edge-cloud https://github.com/jtylab/ind-dist-ai-sec-edge-cloud
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务