『素数 Prime判定和线性欧拉筛法 The sieve of Euler』
<更新提示>
<第一次更新>
<正文>
素数(Prime)及判定
定义
素数又称质数,一个大于1的自然数,除了1和它自身外,不能整除其他自然数的数叫做质数,否则称为合数。
1既不是素数也不是合数。
判定
如何判定一个数是否是素数呢?显然,我们可以枚举这个数的因数,如果存在除了它本身和1以外的因数,那么这个数就是素数。
在枚举时,有一个很简单的优化:一个合数\(n\)必有一个小于等于\(\sqrt{n}\)的因数。
证明如下:
假设一个合数\(n\)没有小于等于\(\sqrt{n}\)的因数。
由于\(n\)为合数,所以除了\(n\)与\(1\)以外,它至少还有两个因数\(p_1(p_1>\sqrt{n})\)和\(p_2(p_2>\sqrt{n})\),满足\(p_1p_2=n\)。
与\(p_1>\sqrt{n},p_2>\sqrt{n}\)矛盾,故假设不成立。
所以我们得到了\(O(\sqrt n)\)效率的素数判定算法。
\(Code:\)
inline bool check(k)
{
    for(int i=2;i*i<=k;i++)
    if(k%i==0)return 0;
    return 1;
}
筛法(Sieve)求素数
现在有一个新的问题模型,如果我们需要求解\(1-n\)的所有素数,那么直接用判定法效率显然太低了。我们需要更高效率的算法,由此我们引入筛法。
埃氏筛法(The sieve of Eratosthenes)
这是筛法思想的基本模型。根据算数基本定理,我们得知:
\]
即任意一个数\(k\)都是由若干素数相乘得到的。
那么我们可以枚举\(2-n\)的每一个数,如果这个数没被标记,则说明这个数是素数,记录这个数,并标记这个数的所有倍数不是素数。
那么这样就可以求解\(1-n\)的所有素数了。时间复杂度为\(O(n\ ln(ln\ n))\)。
实现
这就是OI竞赛中最常用的素数求解算法了,实现也非常简单。
\(Code:\)
#include<bits/stdc++.h>
using namespace std;
int cnt=0,n,flag[100080]={},Prime[100080]={};
inline void sieve(void)
{
	for(int i=2;i<=n;i++)
	{
		if(!flag[i])Prime[++cnt]=i;else continue;
		for(int j=i*2;j<=n;j+=i)flag[j]=true;
	}
}
int main(void)
{
	cin>>n;
	sieve();
	for(int i=1;i<=cnt;i++)cout<<Prime[i]<<" ";
	cout<<endl;
}
欧拉筛法(The sieve of Euler)
欧拉筛法就是基于埃氏筛法的优化。
在模拟埃氏筛法的过程中,我们不难发现有很多合数会被它的各个素因子筛好几次,我们可以基于这种情况进行优化:每个合数必有一个最小素因子,用这个因子筛掉合数
所以,我们直接利用之前求出的素数进行筛数,如果发现当前这个数已经是之前某个素数的倍数时,那就说明这个数在以后会由某个更大的数乘以这个小素数筛去,同理,之后的筛数也是没有必要的,这时候就可以跳出循环了。
这样,我们就能保证每一个数只被筛一次,就实现了线性时间复杂度的筛法。
实现
欧拉筛法和埃氏筛法大体相似,但细节有所不同,注意不要搞混。
\(Code:\)
#include<bits/stdc++.h>
using namespace std;
int cnt=0,n,flag[100080]={},Prime[100080]={};
inline void seive(void)
{
	for(int i=2;i<=n;i++)
	{
		if(!flag[i])Prime[++cnt]=i;
		//注意,这里没了continue,因为在筛某个数时需要用到它的最大因数,而这个数可能是个合数,所以不管是素数还是合数,都要执行以下的筛数过程
		for(int j=1;j<=cnt&&i*Prime[j]<=n;j++)
		{
			flag[i*Prime[j]]=1;
			if(i%Prime[j]==0)break;
		}
	}
}
int main(void)
{
	cin>>n;
	seive();
	for(int i=1;i<=cnt;i++)cout<<Prime[i]<<" ";
	cout<<endl;
}
<后记>
『素数 Prime判定和线性欧拉筛法 The sieve of Euler』的更多相关文章
- HDU 3823 Prime Friend(线性欧拉筛+打表)
		
Besides the ordinary Boy Friend and Girl Friend, here we define a more academic kind of friend: Prim ...
 - [洛谷P3383][模板]线性筛素数-欧拉筛法
		
Description 如题,给定一个范围N,你需要处理M个某数字是否为质数的询问(每个数字均在范围1-N内) Input&Output Input 第一行包含两个正整数N.M,分别表示查询的 ...
 - 欧拉筛法模板&&P3383 【模板】线性筛素数
		
我们先来看欧拉筛法 •为什么叫欧拉筛呢?这可能是跟欧拉有关 •但是为什么叫线性筛呢?因为它的复杂度是线性的,也就是O(n),我们直接来看代码 #include<cstdio> #inc ...
 - 素数判断-----埃氏筛法&欧拉筛法
		
埃氏筛法 /* |埃式筛法| |快速筛选素数| |15-7-26| */ #include <iostream> #include <cstdio> using namespa ...
 - BZOJ 2818 Gcd 线性欧拉
		
题意:链接 方法:线性欧拉 解析: 首先列一下表达式 gcd(x,y)=z(z是素数而且x,y<=n). 然后我们能够得到什么呢? gcd(x/z,y/z)=1; 最好还是令y>=x 则能 ...
 - POJ2909_Goldbach's Conjecture(线性欧拉筛)
		
Goldbach's Conjecture: For any even number n greater than or equal to 4, there exists at least one p ...
 - 2018牛客网暑期ACM多校训练营(第三场) H - Diff-prime Pairs - [欧拉筛法求素数]
		
题目链接:https://www.nowcoder.com/acm/contest/141/H 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 262144K,其他语言524288K ...
 - 素数筛总结篇___Eratosthenes筛法和欧拉筛法(*【模板】使用 )
		
求素数 题目描述 求小于n的所有素数的数量. 输入 多组输入,输入整数n(n<1000000),以0结束. 输出 输出n以内所有素数的个数. 示例输入 10 0 示例输出 4 提示 以这道题目为 ...
 - BNU 12846 LCM Extreme 最小公倍数之和(线性欧拉筛选+递推)
		
LCM Extreme Time Limit: 3000ms Memory Limit: 131072KB This problem will be judged on UVALive. Orig ...
 
随机推荐
- Tomcat7配置Https
			
使用的是UCloud的免费证书: 教程: https://docs.ucloud.cn/security/ussl/index 购买证书的地址: https://console.ucloud.cn/u ...
 - SparkStreaming
			
Spark Streaming用于流式数据的处理.Spark Streaming支持的数据输入源很多,例如:Kafka.Flume.Twitter.ZeroMQ和简单的TCP套接字等等.数据输入后可以 ...
 - JS与CSS那些特别小的知识点区别
			
1:target与currentTarget的区别 currentTarget指向的事件绑定的元素,target指向的是你点击的元素 2:attr与jprop在jQuery在API当中的区别 2.1: ...
 - 视频播放—— H5同层播放器接入规范
			
H5同层播放器接入规范 x5-video-player-type 启用H5同层播放器 通过video属性“x5-video-player-type”声明启用同层H5播放器 x5-video-playe ...
 - 2019年3月2日-小雨.md
			
2019年3月2日, 星期六 开学已经一周了,时间好像限制了自己进步的脚步,一个人的精力有限,想做好方方面面实在是太难了,有很多事儿最后都没做的完美.相反,自己应该放下繁琐的包袱,简简单单的干一件事儿 ...
 - 关于 Mybatis 设置懒加载无效的问题
			
看了 mybatis 的教程,讲到关于mybatis 的懒加载的设置: 只需要在 mybatis 的配置文件中设置两个属性就可以了: <settings> <!-- 打开延迟加载的开 ...
 - position属性sticky和fixed的区别比较
			
position属性之fixed fixed总是以body为定位时的对象,总是根据浏览器窗口来进行元素的定位,通过left,right,top,bottom属性进行定位. <!DOCTYPE h ...
 - Go语言基础之结构体
			
Go语言基础之结构体 Go语言中没有“类”的概念,也不支持“类”的继承等面向对象的概念.Go语言中通过结构体的内嵌再配合接口比面向对象具有更高的扩展性和灵活性. 类型别名和自定义类型 自定义类型 在G ...
 - 去掉input在type="number"时右边的上下箭头
			
加了代码之后: input::-webkit-outer-spin-button, input::-webkit-inner-spin-button{ -webkit-appearance: none ...
 - 实验三:分别用for,while;do-while循坏语句以及递归的方法计算n!,并输出算式。
			
源代码: package jiecheng;import java.util.Scanner;public class JieCheng {public static void main(String ...