Numbers

Numbers

https://ac.nowcoder.com/acm/problem/109065

前言:

这题难点在于复杂度分析.

实现:

首先很容易想到k假如不是质数答案为0.因为假如k不是质数,那么它一定可以写成比它小的数相乘.
其次假如答案可行,必定是大于等于k的质数的乘积的形式.因为假设不是比k的质数乘积,就是利用了的质数.这是不行的.
有了这两点,暴力的代码应该是都会写的..区间就等于.然后令以内能被整除,不能被整除的答案即可.至于cal怎么算,是利用容斥算的,是区间的总答案,同时也是乘的那个系数.前面讲到了,这个系数不能是的数.然后递归下就好了.

#include <iostream>
using namespace std;
bool _prime(int x)
 {
     for(int i=2;i<=x/i;i++)
     {
         if(x%i==0)    return false;
    }return true;
 }//O(sqrt(x))

int cal(int n,int k)//计算n以内,能被k整除但不能被2~k-1整除的数量. 
{
    if(!_prime(k))    return 0;
    if(k>=n)        return (k==n);
    int res=n/k;
    for(int i=2;i<k&&i<=n/k;i++)
    {
        res-=cal(n/k,i);
    }return res;
}

int main()
{
    int a,b,k;
    scanf("%d%d%d",&a,&b,&k);
    printf("%d\n",cal(b,k)-cal(a-1,k));
    return 0;
}

复杂度分析:

当k和n都很接近时,复杂度很低.(n/k)
当k很大时,复杂度也很低.(k>=n)
当k很小n很大时,复杂度也不高.(i<=k)
那么复杂度最高的时是:当k取sqrt(n)时,而n取1e9.
此时我们第一个for循环会运行sqrt(1e9)次,然后它的子程序的n就成了sqrt(1e9)了,而它子程序的k的复杂度最高的还是sqrt(n)时.如此分析时间复杂度应是接近根号的.

lpt的小屋 文章被收录于专栏

我想要一份甜甜的爱情

全部评论
设置阈值 很多题目都可以这么做的 阈值有可能不止是sqrt(n) 也有可能是其他值需要具体题目分析
1 回复 分享
发布于 2021-01-06 21:55

相关推荐

11-04 19:05
已编辑
东莞城市学院 单片机
不知道怎么取名字_:你这个要实习两年?哪有这么久的,感觉就是即使你毕业了,但还按实习的话,是不是不用给你缴社保公积金啥的
点赞 评论 收藏
分享
评论
3
收藏
分享

创作者周榜

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