首页 > 其他分享 >线性筛素数

线性筛素数

时间:2023-08-09 22:15:09浏览次数:30  
标签:prime ch int 素数 遍历 线性 isPrime

线性筛素数

原理

线性筛素数是一种用于筛选素数的算法。其基本思想是从2开始,将每个素数的倍数标记为合数,然后从下一个未被标记的数开始,重复这个过程,直到遍历完所有小于等于n的数。

算法流程

  1. 初始化一个布尔型数组is_prime[0...n],将所有元素设置为true
  2. 从2开始遍历数组,如果当前数是素数(即is_prime[i]true),则将其所有的倍数(从2倍开始)标记为合数(即is_prime[j]设为false,其中j = i * k + 1,k为非负整数)。
  3. 继续遍历下一个未被标记的数,重复步骤2,直到遍历完所有小于等于n的数。
  4. 最后,is_prime[i]true的数就是所求的素数集合。

C++代码实现

#include<bits/stdc++.h> // 引入头文件,包含了常用的C++库
#define reg register // 定义宏,将变量声明为寄存器类型
using namespace std; // 使用标准命名空间

// 读取输入,返回一个整数
inline int read(){
    int x=0,f=1;
    char ch=getchar(); // 读取一个字符
    while(ch<'0'||ch>'9'){ // 如果字符不是数字
        if(ch=='-') f=-1; // 如果是负号,设置标志位为负数
        ch=getchar(); // 继续读取下一个字符
    }
    while(ch>='0'&&ch<='9'){ // 如果字符是数字
        x=(x<<1)+(x<<3)+(ch^48); // 将数字转换为二进制并存储在x中
        ch=getchar(); // 继续读取下一个字符
    }
    return x*f; // 返回结果,如果有负号则返回负数
}

// 输出结果,将整数转换为字符串
void write(int x){
    if(x<0){
        putchar('-'); // 如果是负数,输出负号
        x=-x; // 取绝对值
    }
    if(x>9) write(x/10); // 如果数字大于9,递归调用write函数处理十位数
    putchar(x%10+'0'); // 将个位数转换为字符并输出
    return ;
}

const int MAXN=100000008; // 定义常量MAXN为100000008
int n,q,Prime[MAXN],cnt; // 定义变量n, q, Prime[]和cnt
bool isPrime[MAXN]; // 定义布尔数组isPrime[]

// 查找素数并将其存储在Prime[]中
void find(){
    memset(isPrime,1,sizeof(isPrime)); // 将isPrime数组的所有元素初始化为1
    isPrime[1]=0; // 将1标记为非素数
    for(int i=2;i<=n;i++){ // 从2开始遍历到n
        if(isPrime[i]) Prime[++cnt]=i; // 如果i是素数,将其存储在Prime[]中
        for(int j=1;j<=cnt&&i*Prime[j]<=n;j++){ // 在Prime[]中查找i的倍数
            isPrime[i*Prime[j]]=0; // 将找到的倍数标记为非素数
            if(!i%Prime[j]) break; // 如果i能被找到的倍数整除,跳出循环
        }
    }
    return ; // 结束函数
}

int main(){ // 主函数
    n=read(),q=read(); // 从输入中读取n和q的值
    find(); // 调用find函数查找素数并存储在Prime[]中
    for(reg int i=1;i<=q;++i){ // 对于每个查询,从输入中读取一个数字num,并输出对应的素数
        int num=read(); // 从输入中读取num的值
        write(Prime[num]); // 将num对应的素数转换为字符串并输出
        printf("\n"); // 在每个查询后输出换行符
    }
    return 0; // 结束程序
}

例题及题解

题目:给定一个正整数n,编写一个程序找出小于等于n的所有素数。

解答:使用线性筛素数算法,首先创建一个布尔型数组is_prime[0...n],然后从2开始遍历数组,如果当前数是素数,则将其所有的倍数标记为合数。最后,返回is_prime[i]true的数组成的向量即可。

标签:prime,ch,int,素数,遍历,线性,isPrime
From: https://www.cnblogs.com/Nebulary/p/17618113.html

相关文章

  • pytorch的简单线性回归
    2023-08-09本节课视频:https://www.bilibili.com/video/BV1PX4y1g7KC?p=4&spm_id_from=pageDriver&vd_source=bd35cfd68e5bfc28dcf5a57f74e25ae3 首先是创建数据迭代器defload_array(data_arrays,batch_size,is_train=True):dataset=data.TensorDataset(*data_ar......
  • 线性判别分析(LDA)模型笔记
    目录模型概况模型定义模型求解模型概况线性判别方法(LinearDiscriminationAnalysis)是一种经典的线性学些方法,最早由Fisher提出,也叫“Fisher判别分析”。LDA的思想非常朴素,也即是,将样例投影到一条直线上使得同类样例的投影点尽可能近,异类样例的投影点尽可能远,总结六个字就是......
  • 线性基
    背个板子即可。以下是前缀线性基。structxor_set{ inta[32]; inlinevoidadd(longlongval){ for(inti=31;i>=0;i--){ if(!(val&(1ll<<i)))continue; if(a[i])val^=a[i]; else{a[i]=val;break;} } } inlineintquery(i......
  • Alex_Wei 的 《线性代数相关》注
    目录0x00行列式0x01定义0x02基本性质0x10高斯消元法0x11算法介绍0x12矩阵求逆0x13求行列式0x20矩阵树定理0x21算法介绍0x22有向图生成树个数0x23边权积的和0x24边权和的和【咕咕咕】0x25例题P6178【模板】Matrix-Tree定理P3317[SDOI2014]重建P4336[SHOI2016]黑......
  • 【线性代数】向量组/矩阵的秩、正交规范化/正交矩阵
    1.向量组的秩极大线性无关组的定义:注意:同一个向量组可能有很多不同的极大线性无关组,但是这些无关组的向量个数一定是一样的。如果一个向量组只包含一个零向量,则它没有极大线性无关组若向量组本身就线性无关,则其极大线性无关组就是其本身。向量组的秩的定义:向量组的极大......
  • 线性表-顺序表的操作(增删查改,扩容,缩容)
    SeqList.h#include<stdio.h>#include<stdlib.h>typedefstructSeqList{ int*data; intsize; intcapacity;}SL;//顺序表的初始化voidSeqListInit(SL*ps);//顺序表的遍历voidSeqListPrint(SL*ps);//释放空间voidSeqDestroy(SL*ps);//缩容voi......
  • 使用EasyX为线性筛创造动画
    更好的阅读体验:http://t.csdn.cn/pvMNR代码如下:#include<iostream>#include<string>#include<graphics.h>usingnamespacestd;#defineBLOCK_WIDTH70#defineSTART_X80#defineSTART_Y60#defineMAX_PER_LINE10#defineTEXT_COLOR_UNCHOOSE......
  • 线性基
    前线性基就相当于向量的基底,且表示的范围与原来表示的范围相同。插入线性基的过程本质上还是高斯消元,如果被消成全是\(0\)就说明这个向量能被其他向量线性表示。模板这里\(a_i\)表示第\(i\)位为\(1\),前面的全是\(0\)。voidin(llx){ for(inti=63;i>=0;i--) i......
  • 网络流与线性规划24题
    先贴个自己的Dinic板子。//最大流constintinf=0x3f3f3f3f3f3f3f3f;structEdge{ intfrom,to,cap; boolori; Edge(intu,intv,intc,boolo){ from=u,to=v,cap=c,ori=o; }};vector<Edge>edges;vector<int>id[10005];intadd_edge(intu,......
  • 线性同余方程
    Part1:前置知识扩展欧几里得算法(不会的点这里)Part2:求解线性同余方程1、定义给定整数\(a,b,m\),求一个整数\(x\)满足\(a*x\equivb\pmodm\),或者给出无解。因为未知数的指数为\(1\),所以我们称之为一次同余方程,也称线性同余方程。2、求解\(a*x\equivb\pmod......