埃氏筛法与欧拉筛法
2017-09-07 22:26
169 查看
素数的个数
给定整数n,请问n以内有多少个素数?摘自挑战程序程序设计。
要枚举n以内素数,可以用埃氏筛法。这是一个与辗转相除法一样古老的算法。
首先,将2到n范围内的所有整数写下来。其中最小的数字2是素数。将表中所有2的倍数都划去。表中剩余的最小数字是3,它不能被更小的数整除,所以是素数。在将表中所有3的倍数都划去。以此类推,如果表中剩余的最小数字是m时,m就是素数。然后将表中所有m的倍数都划去。像这样反复操作,就能枚举n以内的素数。
代码: 复杂度(nlognlogn)
int prime[MAX_N]; bool is_prime[MAX_N+1]; int sieve(int n) { int p=0; for(int i=0;i<=n;i++) is_prime[i]=true; is_prime[0]=is_prime[1]=false; for(int i=2;i<=n;i++) { if(is_prime[i]) { prime[p++]=i; for(int j=2*i;j<=n;j+=i) is_prime[j]=false; } } return p; }
欧拉筛法则可以把埃氏筛法优化到0(n)
每个合数只用其最小的一个质因数去筛,这便是欧拉筛了
有一句关键并且神奇的代码。
if (i % primes[j] == 0) break;
根据大佬的博客解释:
prime[]数组中的素数是递增的,当i能整除prime[j],那么i*prime[j+1]这个合数肯定被prime[j]乘以某个数筛掉。
因为i中含有prime[j],prime[j]比prime[j+1]小,即i=k*prime[j],那么i*prime[j+1]=(k*prime[j])*prime
[j+1]=k’*prime[j],接下去的素数同理。所以不用筛下去了。因此,在满足i%prime[j]==0这个条件之前以及第一次
满足改条件时,prime[j]必定是prime[j]*i的最小因子。
欧拉筛代码:复杂度o(n)
void euler_sieve(int n) { totPrimes = 0; memset(flag, 0, sizeof(flag)); for (int i = 2; i <= n; i++) { if (!flag[i]) primes[totPrimes++] = i; for (int j = 0; i * primes[j] <= n; j++) { flag[i*primes[j]] = true; if (i % primes[j] == 0) break; } } }
相关文章推荐
- 埃氏筛法与欧拉筛法
- 快速求素数表——埃氏筛法与欧拉筛法
- 埃氏筛法和欧拉筛法的区别
- 欧拉筛法
- 用欧拉筛法优化斯特尼筛法(质数筛法)
- 线性筛(欧拉筛法)简介(洛谷P3383)
- 埃拉托斯特尼筛法和欧拉筛法
- 埃拉托斯特尼筛法 VS 欧拉筛法 (素数筛选) Java
- 【 数学基础】【素数线性筛法--欧拉筛法模板】【普通筛法的优化】
- 素数筛法模板 欧拉筛法
- 模板——欧拉筛法
- 使用欧拉筛法求素数和
- 欧拉筛法和积性函数
- C: 自己写的欧拉(Euler)筛法(已通过测试)
- codeforces 327B(Hungry Sequence) 素数筛法入门(欧拉筛法) Java
- 【数学基础】【欧拉函数解析模板】【欧拉筛法实现求1~n】【求单个n】
- 素数筛(埃式筛法/欧拉筛法)
- 欧拉筛法与积性函数
- UVA - 10820 Send a Table(欧拉筛法)
- BZOJ 2818: 欧拉筛法求gcd(x,y)==k(k为质数)