• 线性筛质数


    暴力

    讲解

    对于每个数,我们用(O(sqrt n))的时间判断是否是质数

    所以时间复杂度是(O(nsqrt n))

    代码就不给出了

    埃式筛法

    讲解

    一个很简单的筛法

    对于每个质数,将它所有的倍数打上标记,表示不是质数

    然后就可以做到(O(nlogn))筛质数了

    代码

    bool vis[MAXN];
    int prime[MAXN],pn;
    void sieve(int x)
    {
    	for(int i = 2;i <= x;++ i)
    	{
    		if(!vis[i]) 
    		{
    			prime[++pn] = i;
    			for(int j = i*2;j <= x;j += i)
    				vis[j] = 1;
    		}
    	}
    }
    

    欧式筛法

    讲解

    由于埃式筛法每个合数会被所有的质因数筛一遍,所以时间复杂度是(O(nlogn))

    但是欧式筛法保证每个合数只会被最小的质因数筛一遍,从而保证了(O(n))的时间复杂度

    它是这么实现的(配代码食用更佳):

    首先外层循环从(2)开始枚举倍数(i),如果发现当前数字不是质数,加入质数的集合

    内层循环枚举已经筛出来的质数(p_j),将(i*p_j)打上标记,如果(i)(p_j)的倍数,直接跳出循环

    为什么可以直接跳出循环呢?

    (j'>j),所以(p_{j'}>p_j),因为(i)(p_j)的倍数,所以(i*p_{j'})也是(p_j)的倍数,它一定会被(p_j)筛掉

    我们希望每个合数被最小的质因数筛掉,而(p_j<p_{j'}),所以可以直接跳出循环

    代码

    bool vis[MAXN];
    int prime[MAXN],pn;
    void sieve(int x)
    {
    	for(int i = 2;i <= x;++ i)
    	{
    		if(!vis[i]) prime[++pn] = i;
    		for(int j = 1;j <= pn && i * prime[j] <= x;++ j)
    		{
    			vis[i * prime[j]] = 1;
    			if(i % prime[j] == 0)//超强优化!
    				break;
    		}
    	}
    }
    
  • 相关阅读:
    Run command in YMAL build pipeline or Release Pipeline
    Create Pipeline for Azure Apps
    Deploy Azure App Service with VS Code
    多线程总结笔记
    @Param注解
    Mac Idea2018.1破解
    空指针异常Caused by: java.lang.NullPointerException: null
    java集合面试题
    在IntelliJ IDEA中使用git
    分支管理
  • 原文地址:https://www.cnblogs.com/PPLPPL/p/13609355.html
Copyright © 2020-2023  润新知