素数筛法知识点整理

素数的定义:除了1和它本身之外,不能被其他整数整除。

一、判定一个正整数n是否为素数的方法:

①定义法:枚举2~n-1这n-2个正整数,如果它们均不能整除n,则可断定n为素数。代码如下:时间复杂度为O(n),如果n为10^9,就不能用此方法。

1 bool is_prime(int n){
2     if(n==1)return false;
3     for(int i=2;i<n;++i)
4         if(n%i==0)return false;
5     return true;
6 }

②从2开始枚举到不大于sqrt(n)的所有正整数,如果它们均不能整除n,则可断定n为素数。为什么只需枚举到sqrt(n)就可以了呢?理由:假设n存在大于或等于sqrt(n)的因子y,则z=n/y必同时为n的因子,且其值小于或等于sqrt(n)(如果z>sqrt(n),那么z*y>n与n=z*y相矛盾)。所以,若n存在相异于1和它本身的因子y>sqrt(n),则必存在小于或等于sqrt(n)的因子,因此,我们只需测试因子到sqrt(n)即可。时间复杂度为O(sqrt(n))。

1 bool is_prime(int n){
2     if(n==1)return false;
3     for(int i=2;i*i<=n;++i)
4         if(n%i==0)return false;
5     return true;
6 }

二、给定一个正整数n(n<=10^6),问n以内有多少个素数?如果采用方法2,时间复杂度最坏能达到1e9!!!超时是毫无疑问的,那么是否有比较快速的判断方法呢?于是两种经典筛法就呼啦呼啦地闪亮登场了。

埃氏筛法:要得到自然数n以内的全部素数,必须把不大于sqrt(n)的所有素数的倍数剔除,剩下的都是素数。时间复杂度只有O(nloglogn),非常接近O(n)。方法:最小的素数是2,先用2去筛,即把2留下,把2的倍数剔除掉;再用下一个质数,也就是3筛,把3留下,把3的倍数剔除掉;接下去用下一个质数5筛,把5留下,把5的倍数剔除掉;不断重复下去......最后剩下的一定是素数,根据定义,下面给出埃氏筛的两种写法:一种是直接判定素数,另一种是边判定素数边保存素数,代码如下:

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int maxn=1000;
 4 bool isp[maxn];int cnt=0,prime[maxn];
 5 void sieve1(){//1、直接判定素数
 6     memset(isp,true,sizeof(isp));
 7     isp[0]=isp[1]=false;
 8     for(int i=2;i*i<maxn;++i){
 9         if(isp[i]){
10             for(int j=i*i;j<maxn;j+=i)
11                 isp[j]=false;
12         }
13     }
14 }
15 void sieve2(){//2、边判定素数边保存素数
16     memset(isp,true,sizeof(isp));
17     memset(prime,0,sizeof(prime));
18     isp[0]=isp[1]=false;
19     for(int i=2;i<maxn;++i){
20         if(isp[i]){//如果isp[i]==true,则i一定是素数
21             prime[cnt++]=i;//保存素数
22             for(int j=i*i;j<maxn;j+=i)
23                 isp[j]=false;
24         }
25     }
26 }
27 int main(){
28     sieve1();//测试代码
29     for(int i=1;i<maxn;++i)
30         if(isp[i])cout<<i<<endl;
31     /*sieve2();
32     for(int i=0;i<cnt;++i)
33         cout<<prime[i]<<endl;*/
34     return 0;
35 }

疑难点一:根据埃氏筛的定义,枚举不大于sqrt(n)的所有素数,将其倍数剔除掉,最终留下的都是素数,为什么只需枚举到sqrt(n)呢?其实原因就是

原文地址:https://www.cnblogs.com/acgoto/p/9488304.html

时间: 2024-07-31 22:46:27

素数筛法知识点整理的相关文章

hdu6069[素数筛法] 2017多校3

/*hdu6069[素数筛法] 2017多校3*/ #include <bits/stdc++.h> using namespace std; typedef long long LL; LL l, r, k; const LL MOD = 998244353LL; int T, n, prime[1100000], primesize; bool isprime[11000000]; void getlist(int listsize) { memset(isprime, 1, sizeof

POJ_3421_X-factor Chains(素数筛法)

X-factor Chains Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 5659   Accepted: 1786 Description Given a positive integer X, an X-factor chain of length m is a sequence of integers, 1 = X0, X1, X2, -, Xm = X satisfying Xi < Xi+1 and Xi

数据库设计教程系列——相关知识点整理

一.教程概述 此数据库设计教程是笔者参考网上资料.相关书籍,以及加上自己多年做数据库设计相关工作的经验积累写就. 数据库设计教程在网上已经有大量类似的资料,并且该领域有不少专业书籍,珠玉在前,心有戚戚. 但这作为唯心六艺之一,我还是希望能够在整理知识的同时,写出自己的一些内容,如果能够对读者 有所帮助,那就最好不过了,谢谢. 本教程主要基于关系型数据库进行讲解,对于维度数据库也会视情况有所涉猎. 下面是整个教程涉及的知识点整理,在撰写教程的过程中,如果有改动,也会调整更新此图. 二.知识点整理

asp.net mvc 3.0 知识点整理 ----- (2).Controller中几种Action返回类型对比

通过学习,我们可以发现,在Controller中提供了很多不同的Action返回类型.那么具体他们是有什么作用呢?它们的用法和区别是什么呢?通过资料书上的介绍和网上资料的查询,这里就来给大家列举和大致的概括下. (1). ActionResult(base):最基本的Action类型,返回其他类型都可以写ActionResult. (2). ContentResult:返回ContentResult用户定义的内容类型. public ActionResult Content() { return

【知识点整理】Oracle中NOLOGGING、APPEND、ARCHIVE和PARALLEL下,REDO、UNDO和执行速度的比较

[知识点整理]Oracle中NOLOGGING.APPEND.ARCHIVE和PARALLEL下,REDO.UNDO和执行速度的比较 1  BLOG文档结构图 2  前言部分 2.1  导读和注意事项 各位技术爱好者,看完本文后,你可以掌握如下的技能,也可以学到一些其它你所不知道的知识,~O(∩_∩)O~: ① 系统和会话级别的REDO和UNDO量的查询 ② NOLOGGING.APPEND.ARCHIVE和PARALLEL下,REDO.UNDO和执行速度的比较(重点)   Tips: ① 本文

HDU 6069 Counting Divisors(区间素数筛法)

题意:...就题面一句话 思路:比赛一看公式,就想到要用到约数个数定理 约数个数定理就是: 对于一个大于1正整数n可以分解质因数: 则n的正约数的个数就是 对于n^k其实就是每个因子的个数乘了一个K 然后现在就变成了求每个数的每个质因子有多少个,但是比赛的时候只想到sqrt(n)的分解方法,总复杂度爆炸,就一直没过去,然后赛后看官方题解感觉好妙啊! 通过类似素数筛法的方式,把L - R的质因子给分解,就可以在O(nlogn)的时间之内把所以的数给筛出来. 代码: /** @xigua */ #i

【Android 面试基础知识点整理】

针对Android面试中常见的一些知识点整理,Max 只是个搬运工,感谢本文中引用文章的各位作者,给大家分享了这么多优秀文章,对于其中的解析,是原作者个人见解,有错误和不准确的地方,也请大家积极指正. 本文将持续更新,同时我也将其放在Github上:Point-of-Android 同时可以看Max的个人博客:海上钢琴师 Android中的异步任务机制 Android中AsyncTak的使用与源码分析 http://blog.csdn.net/bboyfeiyu/article/details/

poj 2478 Farey Sequence(基于素数筛法求欧拉函数)

http://poj.org/problem?id=2478 求欧拉函数的模板. 初涉欧拉函数,先学一学它基本的性质. 1.欧拉函数是求小于n且和n互质(包括1)的正整数的个数.记为φ(n). 2.欧拉定理:若a与n互质,那么有a^φ(n) ≡ 1(mod n),经常用于求幂的模. 3.若p是一个质数,那么φ(p) = p-1,注意φ(1) = 1. 4.欧拉函数是积性函数: 若m与n互质,那么φ(nm) = φ(n) * φ(m). 若n = p^k且p为质数,那么φ(n) = p^k - p

·DP」知识点整理

一.最长公共子序列(LCS Longest Common  Subsequence) 第一,先说区别,最长公共子串和最长公共子序列是不一样的. 最长公共子串不许是连续的,而最长公共子序列可以是不联系的. 网络上解释的子序列: 一个字符串S,去掉零个或者多个元素所剩下的子串称为S的子序列.最长公共子序列就是寻找两个给定序列的子序列,该子序列在两个序列中以相同的顺序出现,但是不必要是连续的. 例如 X=ABCBDAB Y=BDCABA BCA是X和Y的一个公共子序列,但是不是X和Y的最长公共子序列,