首页 > 其他分享 >欧拉筛法求素数

欧拉筛法求素数

时间:2023-03-30 22:49:12浏览次数:37  
标签:Prime 12 筛法 合数 因子 最小 素数 欧拉

在开筛之前,我们要理解一个很好理解的概念,任何一个合数可以拆成一个最小素数和另一个数(可能质数可能合数)的乘积
这个最小素数即为这个合数的最小质因子
//比如 12=2*6,此时2就是12的最小质因子,当然亦有12=3*4,可以看到3也是12的质因子,但不是最小的质因子
//而且,对于一合数a=b*q,b为a的最小质因子,a只有一种分解方法,也就是说,对于a,它仅能被最小素因子整除,也就是说,a只能被b筛选一次
//而欧拉筛正是用最小质因子来筛掉合数的,对于一个数,我们遍历他的素数倍(这里的素数是已经找到的素数),将其标记为合数
//并且为了防止重复筛选,也就是防止非最小质因子拆分,我们设计了if (k % Prime[j] == 0)break;这个条件主要是针对k为合数的筛选
//举个例子,若能整除,设倍数为n,则k=n*Prime[j],倘若我们在这里不break,那么下一个我们要标记的合数为i*Prime[j+1]=Prime[j]*n*Prime[j+1]
//即标记合数=Prime[j]*n*Prime[j+1],显然,当k=n*Prime[j+1]时,这个合数又会被筛一次,为了贯彻欧拉筛的分解最小质因数的筛法
//我们只取k为这个合数的最小质因数时的那一次筛,显然作为质因子来说,Prime[j]<Prime[j+1],所以我们决定在k=n*Prime[j+1]时来筛选这个合数

//这样的话这个合数的分解就会分解为最小质因子与k的乘积

//还是以12为例子。遍历时,当k=8,j=1时,Prime[j]=2,此时k%Prime[j]==0,若继续筛第j+1,Prime[j+1]=3,则此时的合数为8*3=24
// 但是显然,k=4*2(此时n=4),所以合数P=4*2*3,故当k=4*3时还会被筛一遍,对于两种情形,k=4*2,其质因子为3,对k=4*3,其质因子为2,显然取最小,故k=4*3时筛选
//由此,我们可以知道,欧拉筛对每个数只会筛掉一次,相较于埃氏筛对于12的多次重复筛(对i=2和i=3都会筛到12),时间复杂度有更一步的下降
//下面是实现

 

 1 #include<stdio.h>
 2 #include<stdbool.h>
 3 #include<algorithm>
 4 #include<stdlib.h>
 5 #include<string.h>
 6 #include<math.h>
//头文件插多了,别在意 7 #define MAXSIZE 1000 8 9 int* euler_sieve(int *cnt)//欧拉筛 10 { 11 int n; 12 scanf("%d", &n);//左边界 13 bool* IsPrime = (bool*)malloc(sizeof(bool) * (n + 1));//若i为素数,则IsPrime[i]=true,否则为false 14 memset(IsPrime, true, n + 1);//初始默认全为素数 15 IsPrime[0] = IsPrime[1] = false;//我们从2开始判断,对1和0这两个合数我们首先初始化为false 16 int* Prime = (int*)malloc(sizeof(int) * MAXSIZE);//用来存找到的素数 17 //准备工作结束 18 for (int k = 2; k <=n; k++)//开筛 19 { 20 if (IsPrime[k])//若是素数加入素数数组 21 Prime[(* cnt)++] = k; 22 for (int j = 0; j, j < *cnt && k * Prime[j] <= n; j++)//不论k是否是素数都会被用来筛选其最下质因数倍的合数 23 { 24 IsPrime[k * Prime[j]] = false;//合数标记 25 if (k % Prime[j] == 0)break;//重点 26 } 27 } 28 return Prime; 29 } 30 int main() 31 { 32 int cnt = 0;//素数个数统计 33 int *Prime=euler_sieve(&cnt); 34 for (int i = 0; i <cnt; i++) 35 { 36 printf("%d\n", Prime[i]); 37 } 38 return 0; 39 }

 

标签:Prime,12,筛法,合数,因子,最小,素数,欧拉
From: https://www.cnblogs.com/WKWKSL/p/17274598.html

相关文章

  • 素数环
    #include<cstdio>#include<iostream>#include<cstring>usingnamespacestd;boolisprime[40];//用于判断是否为素数boolisused[20];//用于判断是否重复使用。i......
  • 浅析数论--埃氏筛/欧拉筛/杜教筛
    \(\mathcal{0x01绪论}\)\(\mathcal{质数的判定试除法or六倍原理}\)一个合数的约数总是成对出现的,如果\(d|n\)(\(d\)能被\(n\)整除),那么\((n/d)|n\),因此我们判断一个......
  • AcWing 874. 筛法求欧拉函数
    \(AcWing\)\(874.\)筛法求欧拉函数一、题目描述给定一个正整数\(n\),求\(1∼n\)中每个数的欧拉函数之和。输入格式共一行,包含一个整数\(n\)。输出格式共一行,包......
  • 数论基础1(质数判断,分解质因数,筛法,优化筛法,约数,约数个数,约数之和)
    模板://质数判定--试除法//朴素O(N)boolis_prime(intn){ if(n<2)returnfalse; for(inti=2;i<n;i++) { if(n%i==0)returnfalse; } returntrue;}//......
  • C01素数之和
    publicclassA01素数之和{publicstaticvoidmain(String[]args){intsum=0;//累加求和for(inti=2;i<=100;i++){if(isSS(i)){//如果i是素数,就累加到su......
  • 6-2 计算素数和
    本题要求计算输入两个正整数x,y(x<=y,包括x,y)素数和。函数isPrime用以判断一个数是否素数,primeSum函数返回素数和。实现代码:defisPrime(x):foriinrange(2,x):......
  • 欧拉序+ST表 O(nlogn+q)求LCA
    欧拉序:每次遍历到树上的一个点,就加进欧拉序如123​45这颗树的欧拉序是121343431这样我们可以发现一个重要的性质:两个点的LCA是欧拉序之间dep最小的点......
  • [线筛|欧拉筛]线性筛选素数
    来源:模板题目描述:用线行筛筛选素数,将指定范围的素数找出,达到O(n)的效果。思路时间复杂度0(n)思路任意值必然可以被分解为:​​a=b1^c1*b2*c2*...​​​例如​​9=3^3,15=3*5,......
  • [pat乙]1007 素数对猜想
    1007素数对猜想(20分)让我们定义dn为:dn=pn+1-pn,其中pi是第i个素数。显然有d1=1且对于n>1有dn是偶数。“素数对猜想”认为“存在无穷多对相邻且差为2的素数”......
  • [pat乙]1013 数素数
    1013数素数(20分)算法标签:欧拉筛1013数素数(20分)令P​i​​表示第i个素数。现任给两个正整数M≤N≤10​4​​,请输出P​M​​到P​N​​的所有素数。......