线性筛素数
学习这个算法的时候看了这位大佬的题解
背景
最近遇到一个问题,需要判断大量的数是否是素数,暴力做法会TLE,所以在寻找解决办法的时候了解了欧拉筛法(线性筛法)
代码
这里以洛谷P3383为例
#include <iostream> #include <cstring> using namespace std; bool isPrime[114514191]; int Prime[114514191]; void solve(int n) { int cnt = 0; memset(isPrime, true, sizeof(isPrime)); isPrime[1] = false; for(int i = 2; i <= n; i++) { if(isPrime[i]) { Prime[++cnt] = i; } for(int j = 1; j <= cnt && i * Prime[j] <= n; j++) { isPrime[i * Prime[j]] = false; if(i % Prime[j] == 0) break; } } } int main(void) { ios::sync_with_stdio(0); int n, q; cin >> n >> q; solve(n); while(q--) { int k; cin >> k; cout << Prime[k] << endl; } return 0; }
时间复杂度:
算法原理
欧拉筛的基本原理是利用因数分解的思想来筛去合数,对于任一合数均可被拆分为2
开始(因为2本身就素数,所以直接从它开始判断)枚举每一个素数,即if(i % Prime[j] == 0) break;
由于i
的最小质因数。
正确性证明(出自大佬博客)
设任一要被筛去的合数C
的最小质因数为p
,令B = C / p
,则B的最小质因数一定不小于p
(B
的最小质因数一定不小于p
,所以内层在结束break前一定会遇到p
,(博客原话是:所以p
之前一定不会break),这样就可以保证c
会被筛去。
The End
本文作者:dbywsc
本文链接:https://www.cnblogs.com/dbywsc/p/17890872.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步