zoukankan      html  css  js  c++  java
  • 7.13 线性筛素数

    今天我们讲了一大堆数论的东西,目前本人稍微掌握一些的便是素数筛法,下面为了保护着珍贵的遗产,我决定写一篇博客来记录一下,

    谈到素数筛法,相信大家岁熟悉的是暴力筛,我们大家只需要把数n的前1到sqrt(n)中所有的质数拿来和这个数n除一下看一下能否整除,如果能够整除,说明这个n是素数,然后就依次这样判定。

    还有一种筛法是E筛,就是把每个数自己所有的倍数全部筛掉,当然其实你会发现我们只要把所有素数的倍数全部筛掉就可以了。

    然后上面两种筛法都不是我们今天的重点,我们今天要讲的筛法是线性筛法——即通过某种方式使每个数都被自己的最小素因子筛去即可。注意:是最小的素因子!!!

    算法实现

    其实实现还是非常的简单了,我们从小到大依次枚举i,再枚举最小质因子pj,将i*pj筛去

    而当i mod pj =0 时break出来,因为更大的pk,i*pk会被pj筛去而不是pk

    举一个非常简单的例子,就是如果说现在我们正在检查数字6,我们正在用他筛去后面的一些合数,但是现在我们碰到了数字3,3是一个素数,并且6除3余0所以这时候我们应该把6break掉,因为在后面的后面早晚会碰见一个合数既被3整除又被6整除,就会被访问两次,为了降低复杂度先break掉就只是他访问了一次,节约了时间。

    下面上一个代码:

    大家看一看应该也就懂了:

    #include<bits/stdc++.h>
    using namespace std;
    bool mark[1000005];
    int p[1000005];
    int main()
    {
    	memset(mark,false,sizeof(mark));
    	int n;
    	int cnt=0;
    	scanf("%d",&n);
    	for(int i=2;i<=n;++i)//枚举筛第i个数 
    	{
    		if(!mark[i]) p[++cnt]=i;
    		for(int j=1;j<=cnt&&i*p[j]<=n;++j)
    		{
    			mark[i*p[j]]=true;
    			if(i%p[j]==0) break;//important
    		}
    	}
    	for(int i=1;i<=cnt;++i)
    	{
    		printf("%d ",p[i]);
    	} 
    	return 0;
    }
    
  • 相关阅读:
    百度缓存
    thrift文件编写
    thrift初窥
    Shutil模块介绍
    多线程访问网站的爬虫的问题
    点滴记录python linux中的个人经验
    Yii框架的form处理
    使scrapy支持ftp下载
    mojoportal学习——文章翻译之站点图标
    mojoportal学习之特色模块对Artisteer2.4生成的模板的支持
  • 原文地址:https://www.cnblogs.com/mudrobot/p/13330088.html
Copyright © 2011-2022 走看看