学习笔记--数论--欧式线性筛素数
线性筛法,
即是筛选掉所有合数,留下质数
我们知道合数可以由一个质数数与另一个数相乘得到,而比一个合数数大的质数和该合数的乘积可用一个更大的合数和比其小的质数相乘得到
这也是if(! ( i % prime[j]) )break;的含义,
这也是线性筛法算质数表的关键所在
原理:
-
任何一个合数都可以表示成一个质数和一个数的乘积
-
假设A是一个合数,且,这里x也是一个合数,那么有: ; (假设y质数,x合数)
; (假设a是质数,且a < x)->
即一个合数(x)与一个质数(y)的乘积可以表示成一个更大的合数(Z)与一个更小的质数(a)的乘积这也是理解代码中 的关键
例如: 如果i = 8; 那么由于i%2 == 0; 因此对于i=8就只需要检查即可,因为对于大于的质数,像3,有: 也就是说并不需要在8时检查,在12时才检查
#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <cstring>
using namespace std;
const int maxn=10000000+10;
int n,m;
bool is_Prime[maxn];
int total;//计数
int primenum[maxn];//线性筛法寻找素数
void pick_up_Prime()
{
memset(is_Prime,1,sizeof(is_Prime));
memset(primenum,0,sizeof(primenum));
is_Prime[0]=0;
is_Prime[1]=0;//特判
for(register int i=2;i<=n;i++)
{
if(is_Prime[i]) primenum[total++]=i;
for(register int j=0; j<total && i*primenum[j]<=n;j++)
{
is_Prime[i*primenum[j]]=0;
if(i%primenum[j]==0) break; }
}
}
int main()
{
cin>>n>>m;
pick_up_Prime();
for(register int i=1;i<=m;i++)
{
int x;
scanf("%d",&x);
if(is_Prime[x])puts("Yes");
else puts("No");
}
return 0;
}
在洛谷上欧式筛法比埃式筛法跑的更快(至少我的是这样),但带来的是更多空间消耗。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?