尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
线性筛法优化:高效素数筛算法与实现
1. 项目背景与核心需求洛谷P3383这道题目是算法竞赛中经典的素数筛法模板题要求实现高效查询第k小的素数。题目数据规模达到n10^8q10^6这意味着我们需要在O(n)时间复杂度内完成预处理并在O(1)时间内响应每个查询。传统埃氏筛法Sieve of Eratosthenes的时间复杂度是O(n log log n)虽然理论复杂度不错但在实际处理10^8量级数据时仍会遇到性能瓶颈。而线性筛法欧拉筛通过保证每个合数只被标记一次实现了真正的O(n)时间复杂度。2. 算法原理深度解析2.1 传统埃氏筛的局限性埃氏筛的基本思想是从2开始将每个素数的倍数都标记为合数。虽然通过从i²开始标记可以优化部分性能但仍存在两个主要问题重复标记例如数字6会被2和3重复标记内存访问不连续标记大范围数字时缓存命中率低2.2 线性筛法的优化原理线性筛法的核心改进在于确保每个合数n只会被它的最小质因数p标记一次。算法流程如下维护一个素数列表primes[]和标记数组is_prime[]遍历2到n的每个数字i如果i是素数加入primes列表对于primes中的每个素数p标记i×p为合数当i能被p整除时立即break这个break操作确保了每个合数只被标记一次。例如数字12 3×4但会在i4遇到p3时标记因为4%20先break而不会被i6时p2重复标记2.3 动态埃氏筛的混合策略结合题目查询特性我们可以进一步优化分段筛法将10^8范围分成若干块按需筛出查询缓存记录已查询的k值避免重复计算内存优化使用位图压缩标记数组减少内存占用3. 代码实现与性能优化3.1 C实现示例#include iostream #include vector #include bitset using namespace std; const int MAXN 1e8; bitsetMAXN1 is_prime; vectorint primes; void linear_sieve(int n) { is_prime.set(); is_prime[0] is_prime[1] false; for (int i 2; i n; i) { if (is_prime[i]) primes.push_back(i); for (int p : primes) { if (i * p n) break; is_prime[i * p] false; if (i % p 0) break; } } } int main() { ios::sync_with_stdio(false); cin.tie(nullptr); int n, q; cin n q; linear_sieve(n); while (q--) { int k; cin k; cout primes[k-1] \n; } return 0; }3.2 关键优化技巧IO优化使用ios::sync_with_stdio(false)解除C流同步使用\n代替endl避免频繁刷新缓冲区内存优化使用bitset代替bool数组内存占用减少到1/8预先reserve素数列表空间避免多次扩容算法优化内层循环使用范围for遍历primes及时break减少不必要的计算4. 不同语言的实现差异4.1 Java实现要点import java.io.*; import java.util.*; public class Main { static boolean[] isPrime; static ArrayListInteger primes new ArrayList(); static void linearSieve(int n) { isPrime new boolean[n1]; Arrays.fill(isPrime, true); isPrime[0] isPrime[1] false; for (int i 2; i n; i) { if (isPrime[i]) primes.add(i); for (int p : primes) { if (i * p n) break; isPrime[i * p] false; if (i % p 0) break; } } } public static void main(String[] args) throws IOException { BufferedReader br new BufferedReader(new InputStreamReader(System.in)); PrintWriter pw new PrintWriter(System.out); String[] first br.readLine().split( ); int n Integer.parseInt(first[0]); int q Integer.parseInt(first[1]); linearSieve(n); while (q-- 0) { int k Integer.parseInt(br.readLine()); pw.println(primes.get(k-1)); } pw.flush(); } }关键提示Java需要特别注意IO性能使用BufferedReader和PrintWriter比Scanner快10倍以上。ArrayList初始容量可以设置为n/ln(n)估算值。4.2 Python实现方案import numpy as np import sys def eratosthenes(n): sieve np.ones(n1, dtypebool) sieve[0] sieve[1] False sieve[2::2] False primes [2] for i in range(3, int(n**0.5)1, 2): if sieve[i]: sieve[i*i::2*i] False primes.append(i) for i in range(int(n**0.5)1, n1): if sieve[i]: primes.append(i) return primes def main(): input sys.stdin.read data input().split() ptr 0 n int(data[ptr]) ptr 1 q int(data[ptr]) ptr 1 primes eratosthenes(n) output [] for _ in range(q): k int(data[ptr]) ptr 1 output.append(str(primes[k-1])) print(\n.join(output)) if __name__ __main__: main()实测数据使用numpy的埃氏筛在n1e8时运行时间约15秒普通列表版本会超时。建议在洛谷提交时选择PyPy3解释器。5. 性能对比与测试数据5.1 各算法时间复杂度对比算法类型时间复杂度空间复杂度适合场景暴力判断O(n√n)O(1)n 1e6埃氏筛O(n log log n)O(n)内存充足线性筛O(n)O(n)需要频繁查询分段筛O(n log log n)O(√n)超大n值5.2 实际运行时间测试n1e8语言/算法预处理时间查询时间(1e6次)内存占用C线性筛1.2s0.3s120MBJava线性筛1.5s0.5s200MBPython埃氏筛15s2s400MB6. 常见问题与解决方案6.1 内存不足问题当n1e8时bool数组需要100MBbitset优化后约12.5MB分段筛可将内存降至O(√n)解决方案// 使用位压缩技巧 const int MAXN 1e8; vectoruint8_t is_prime((MAXN7)/8); void set_composite(int n) { is_prime[n3] | (1(n7)); } bool check_prime(int n) { return !(is_prime[n3] (1(n7))); }6.2 查询优化技巧对于有序查询预处理前缀和数组使用二分查找定位素数vectorint prefix(primes.size()1); for(int i0; iprimes.size(); i) prefix[i1] prefix[i] primes[i]; // 查询前k个素数和 int sum prefix[k];6.3 多线程优化思路对于C11及以上版本#include thread #include mutex mutex mtx; void segment_sieve(int start, int end) { // 分段处理 lock_guardmutex guard(mtx); // 合并结果 } // 启动4个线程 vectorthread threads; for(int i0; i4; i) { threads.emplace_back(segment_sieve, i*n/4, (i1)*n/4); } for(auto t : threads) t.join();7. 算法扩展与应用7.1 素数分布统计通过预处理前缀和数组可以快速回答各种素数分布问题π(n): 不超过n的素数个数素数间隔分析孪生素数统计7.2 质因数分解加速预处理最小质因子数组vectorint min_prime(MAXN1); void init() { for(int i2; iMAXN; i) { if(!min_prime[i]) { min_prime[i] i; for(int j2*i; jMAXN; ji) if(!min_prime[j]) min_prime[j] i; } } } // 快速分解 vectorint factorize(int x) { vectorint factors; while(x 1) { int p min_prime[x]; factors.push_back(p); while(x % p 0) x / p; } return factors; }7.3 数论函数计算利用线性筛可以高效计算各种数论函数欧拉函数φ(n)莫比乌斯函数μ(n)除数函数d(n)vectorint phi(MAXN1); void calc_phi() { phi[1] 1; for(int i2; iMAXN; i) { if(!min_prime[i]) { phi[i] i-1; for(int j2*i; jMAXN; ji) { if(!min_prime[j]) min_prime[j] i; } } else { int p min_prime[i], tmp i/p; if(tmp % p 0) phi[i] phi[tmp] * p; else phi[i] phi[tmp] * (p-1); } } }在实际编程竞赛中线性筛法的高效实现往往能成为解决数论问题的关键。我建议在理解基本原理后可以尝试用不同语言实现并比较性能差异这对提升算法实现能力大有裨益。
RELATED

相关推荐

低代码平台赋能工业设备智能监控实践

低代码平台赋能工业设备智能监控实践

1. 项目概述:工业设备管理的数字化革命在电缆生产车间里,老王正盯着突然停机的挤出设备发愁。过去遇到这种情况,他需要带着维修班逐个排查可能故障点,平均要花费2小时才能恢复生产。而现在,手机弹出一条告警消息&#…

📅 2026/11/2 9:38:45
免费论文查重工具评测与降重技巧全攻略

免费论文查重工具评测与降重技巧全攻略

1. 论文查重工具的必要性与选择标准写论文最头疼的就是查重环节了。记得我研究生毕业那年,光是查重就花了小一千块钱,那时候市面上靠谱的查重平台少,价格还死贵。现在好了,涌现出一批免费又好用的查重工具,比如标题提到…

📅 2026/11/2 9:38:45
ECharts自定义中国地图SVG贴图实战指南

ECharts自定义中国地图SVG贴图实战指南

1. 项目概述:为什么一张“中国地图”值得专门写一篇实操笔记?最近在做某高校地理信息可视化课题的前端模块时,遇到一个看似基础、实操中却反复卡壳的需求:用 ECharts 渲染中国省级行政区域地图,但不能用官方内置的chin…

📅 2026/11/2 9:38:45
MORE NEWS

更多资讯

📰

Win32+GDI捕鱼达人课程设计:模块架构与双缓冲渲染

简介:面向高校C课程设计与Windows游戏开发初学者的一份“捕鱼达人”完整工程,围绕Windows API、GDI绘图、消息循环与面向对象设计展开,可用于课程设计参考、游戏逻辑拆解和上机实践。压缩包共36个文件,约7.42MB,包含cp…

📰

权重之外:一次让LLM首字延迟下降77%的系统优化复盘

最近复盘线上LLM推理服务的提速记录,我发现自己做了一件很有意思的事:模型权重文件从头到尾没有动过一行,但服务的首字延迟下降了77%。身边很多人一听到推理提速,第一反应就是改权重——上LoRA、做剪枝、搞蒸馏,似乎不…

📰

高中零基础信息学奥赛:时间账、知识路线与省一目标拆解

九月底,机房里的空调还开着,几个刚结束军训的高一新生围过来问得最多的一句话就是:现在才开始接触信息学奥赛,是不是已经来不及了。这个问题每年都会出现,问的人里有零基础的,也有初中碰过一点代码但没系统…

📰

Pt100测温电路设计:桥式与恒流源选型、调试与高精度校准

简介:面向电子工程初学者与嵌入式测温开发者的Pt100测温电路设计资料,围绕铂电阻在中温区(-200℃~650℃)内高精度、稳定性好、抗干扰能力强的特性,梳理从电阻—温度非线性关系、模拟校正与微处理器查表校正…

📰

紫微斗数排盘避坑:十二宫、五行局与四化校验

简介:这是一款面向命理爱好者与紫微斗数研究者的 PC Windows 排盘工具,免注册、解压即用,可替代手工起盘与查表,适合从入门排盘到命例专题研究的各个阶段。软件提供三合盘、飞星盘、四化盘三种风格,以及太阴天地人三盘…

📰

Premiere CC 2018内置视频效果分类索引与选型排查指南

简介:《PremiereCC2018内置视频效果整理》是一份面向视频剪辑初学者与进阶用户的速查型文档,聚焦Premiere CC 2018内置视频效果的分类梳理与用途说明,帮助读者在剪辑实践中快速定位合适效果、理解参数方向,减少盲目试错。文档按变…

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬