首页 > 其他分享 >素数个数 <埃式筛 && 欧拉筛>

素数个数 <埃式筛 && 欧拉筛>

时间:2024-11-13 11:45:33浏览次数:1  
标签:prime false int 个数 素数 bool judge

求 1 ~ 1e7 以内素数的个数

最普通做法(非常超时

int n;
bool judge(int x)
{
    if(x == 1) return false;
    for(int i = 2; i < x; i++)
    {
        if(x % i == 0) return false;
    }
    else return true;
}
int main()
{
    cin >> n;
    int count = 0;
    for(int i = 2; i < n; i++)
    {
        if(judge(i)) count++;
    }
    cout << count;
}

普通做法(超时

//与上面不同的是将judge函数中的搜索范围减少
bool judge(int x)
{
    if(x == 1) return false;
    for(int i = 2; i <= x / i; i++)  //循环中的结束条件更改了
    {
        if(x % i == 0) return false;
    }
    else return true;
}
//更改方法1: i <= sqrt(x)         sqrt函数速度慢,每次循环都会计算一次;开根号可能有精度误差
//更改方法2: int num = sqrt(x)    i <= num  这样只用计算一次sqrt(x)
//更改方法3: i * i <= x           不用sqrt也没有精度误差,但是当i特别大时,i * i可能会溢出变为负数
//更改方法4: i <= x / i           用除法速度可能较慢,但是数据很大时建议使用

埃式筛法(快

核心
筛去得到的素数的倍数 -> 合数
实现筛去
用一个bool类型的数组 或者 bitset(会慢几十ms)来存储每个值是否是素数,当前素数的倍数则是true,后续的遍历只有满足false的条件(即未被筛去)才能进行
不足
一个元素可能会重复筛去,因为它同时是几个素数的倍数
例如
i = 2时,会筛掉4,6,8,10,12,14....
i = 3时,会筛掉9,12....
这里12就筛重复了(这是已经改进了一点的结果,没改进之前,int j = i * 2,重复筛掉的就更多,例如6)

  • 利用了3个for,但是重复筛去的数据更少,1e6的数据平均在15ms
const int N = 1e7 + 10;
bool judge[N];  //bitset<N> judge;  初始化都为false
int n;
int main()
{
    cin >> n;
    int count = 0;
    for(int i = 2; i <= n / i; i++)
    {
        if(!judge[i]) 
            for(int j = i * i; j < n; j += i) judge[j] = true;   //j = i * 2 稍微慢了一点
    }
    for(int i = 2; i <= n; i++)
    {
        if(!judge[i]) count++;
    }
    cout << count;
}
  • 利用2个for,但是重复筛去的元素更多,1e6的数据平均在15ms(时间波动有点大)
const int N = 1e7 + 10;
bool judge[N];  //bitset<N> judge;  初始化都为false
int n;
int main()
{
    cin >> n;
    int count = 0;
    for(int i = 2; i <= n; i++)
    {
        if(!judge[i]) 
        {
            count++;
            for(int j = i * 2; j <= n; j += i) judge[j] = true;   //这里相比上面,int j 不能初始化为i * i,会溢出;并且当 i > sqrt(n) 时仍然会筛掉元素,但是这些元素肯定已经被小于sqrt(n)的数给筛过了
        }
    }
    cout << count;
}

欧式筛法(最快

核心
合数 = 最小的素数 * 另一个数,只有prime[j]是最小的质因数时i才能被筛掉
例如 24 = 3 * 8 = 3 * 2 * 2 * 2 = 2 * 12,要在另一个数为12时才能筛掉,不然就会重复
1e6数据的时间<10ms
核心代码

if(i % prime[j] == 0) break;

代码实现

#include <iostream>

using namespace std;
const int N = 1e6 + 10;
int prime[N];
bool judge[N];

int main()
{
    int n = 1e6, k = 0;
    for(int i = 2; i <= n; i++)
    {
        if(!judge[i]) prime[k++] = i;
        for(int j = 0; j < k; j++) 
        {
            if(i * prime[j] > n) break;
            judge[i * prime[j]] = true;
            if(i % prime[j] == 0) break;
        }//建议多列一串数字寻找原理,或者记下来
    }
    cout << k;
}

标签:prime,false,int,个数,素数,bool,judge
From: https://www.cnblogs.com/PeachyGalaxy/p/18542947

相关文章

  • 用c语言来计算素数和
    #include<stdio.h>intisPrime(intnum){  if(num<2){    return0;//小于2的数不是素数  }  for(inti=2;i*i<=num;i++){    if(num%i==0){      return0;    }  }  return1;......
  • 代码随想录——二叉树-11.完全二叉树的节点个数
    思路一、层序遍历,时间复杂度O(n)二、利用完全二叉树性质,时间复杂度O(logn*logn)(小于O(n))完全二叉树性质:若树深度为h,则前h-1层节点都达到最大值。第h层节点都集中在最左侧的位置完全二叉树要么1.是满二叉树2.最后一层没满满二叉树计算节点数太方便了,直接用公式2^h-1。......
  • C小题目-输入10个数,要求输出其中值最大的元素和该数是第几个数
    #include<stdio.h>intmax(intx,inty){returnx>y?x:y;};intmain(){inta[10];inti,m,n;for(i=0;i<10;i++){printf("请输入第%d个数:",i);scanf("%d",&a[i]);};for(i=0,m=a[0],n=......
  • 如何使用一个包含8000多张图像的鸟类数据集进行YOLOv8目标检测训练。这个数据集已经按
    如何使用一个包含8000多张图像的鸟类数据集进行YOLOv8目标检测训练。这个数据集已经按照YOLO格式进行了标注,并且分为训练集、验证集和测试集,共有六类鸟类。数据集介绍数据集描述数据量:8000多张图像类别数量:6类数据格式:YOLO格式数据集划分:训练集:约6000张验证集:约10......
  • 面向对象基础(2)对象数组、重载与可变个数形参
    3、对象数组数组的元素可以是基本数据类型,也可以是引用数据类型。当元素是引用类型中的类时,我们称为对象数组。案例;定义类Student,包含三个属性:学号number(int),年级state(int),成绩score(int)。创建20个学生对象,学号为1到20,年级和成绩都由随机数确定。问题一:打印出4年级(gra......
  • 每日OJ题_牛客_BC157素数回文_数学_C++_Java
    目录牛客_BC157素数回文_数学题目解析C++代码Java代码牛客_BC157素数回文_数学素数回文_牛客题霸_牛客网描述:现在给出一个素数,这个素数满足两点:1、  只由1-9组成,并且每个数只出现一次,如13,23,1289。2、  位数从高到低为递减或递增,如2459,87631。请你判断一下,这......
  • 前缀素数个数的一点想法
    前缀素数个数的一点想法ideafrompp_orange,08/11/24首先对于狄利克雷卷积,我们有一种视角是设\(f(x)=\sum\limits_{i=1}^{\inf}a_{i}x^{\lni}\),这样我们直接多项式卷积就可以干狄利克雷卷积干的事情,而且方便让多项式的性质和处理手段直接嫁接到狄利克雷卷积上来。我们......
  • 代码随想录算法训练营第十五天| 110.平衡二叉树,257. 二叉树的所有路径, 404.左叶子之
    110.平衡二叉树文章链接:https://programmercarl.com/0110.平衡二叉树.html#题外话题目链接:https://leetcode.cn/problems/balanced-binary-tree/description/classSolution{public://每次都要比较左右子树的高度差是否在1以内,所以递归是要统计子树的高度的intg......
  • L1-009 N个数求和
    目录一、问题描述二、问题分析 三、源码解答四、参考资料一、问题描述本题的要求很简单,就是求N个数字的和。麻烦的是,这些数字是以有理数分子/分母的形式给出的,你输出的和也必须是有理数的形式。1.输入格式输入第一行给出一个正整数N(≤100)。随后一行按格式a1/b1a2/b......
  • cpp_9_8.9【(修改函数)计算一个数的p次幂】
    #include<stdio.h>doublepower(doublen,intp);//ANSI函数原型intmain(void){doublex,xpow;intexp;printf("Enteranumberandthepositiveintegerpower");printf("towhich\nthenumberwillberaised.Enterq......