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); } } }在实际编程竞赛中线性筛法的高效实现往往能成为解决数论问题的关键。我建议在理解基本原理后可以尝试用不同语言实现并比较性能差异这对提升算法实现能力大有裨益。
企业数字化 ERP 产品动态
相关推荐
西电基础实验答案:可复现的电路调试实践笔记 简介:本资源为西安电子科技大学本科阶段基础实验课程的配套答案详解,面向电子信息、通信工程、自动化等相关专业学生,解决实验预习、过程验证与报告撰写中的核心难点。内容覆盖电路分析(欧姆定律、基尔霍夫定律、RLC元件特性&… · 2026/11/5 14:54:51
从传播损耗到阵元波形:Kraken复数声场提取与Matlab实现 简介:这份资源面向水声通信、海洋声学方向的研究人员与工程技术人员,提供基于 Matlab 的 Kraken 计算工具,用于求解水声传播损耗并模拟水平阵、垂直阵各阵元的接收波形,可服务于声纳系统设计、阵列性能评估与信号检测等场景。压缩… · 2026/11/5 3:42:53
残缺美学:不完美中的创造力与价值 1. 维纳斯之美:残缺中的完美哲学古希腊雕塑家阿历山德罗斯创作的米洛的维纳斯,以其缺失的双臂成为艺术史上最著名的形象之一。这座高约2米的帕罗斯大理石雕像,现存于卢浮宫,每年吸引数百万游客驻足。有趣的是,正是这种… · 2026/11/5 9:54:03
ADS122U04IPWR+STM32F427ZI工业级温度测量信号链设计 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/5 14:10:41
UART接口24位ADC搭配RS485,解决远距离温度监控难题 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/5 14:10:41
UART接口24位ADC搭配PIC18F46K22的RTD与热电偶测温实践 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/5 14:10:41
GD32E10x官方例程入门:从GPIO点灯到串口调试 简介:这份GD32E10x系列官方例程面向嵌入式硬件与单片机开发者,基于ARM Cortex-M3内核,汇集兆易创新GD32E10x的示例代码,适合工业控制、消费电子、通信设备等场景的学习、验证与二次开发。压缩包共935个文件,约11.16MB&… · 2026/11/5 13:52:29
基于Django的运维平台实战:资产、发布、巡检、告警一体化 简介:这份资源是一套基于Django框架开发的运维平台源码,面向具备Python基础、希望了解Web运维系统实现思路的开发者与运维人员,可用于学习主机管理、服务监控、日志查看、任务调度、权限控制、资源统计、脚本执行与故障告警等常见运维模块的落… · 2026/11/5 13:49:27
基于ADS122U04IPWR与STM32F427ZI的工业测温方案设计 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/5 13:22:54
双极步进电机控制实战:DRV8818PWPR与PIC18F86K22驱动调试 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/5 10:27:59
STM32F207ZG + DRV8818PWPR 步进电机驱动实战解析 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/5 10:28:03
DRV8818PWPR+dsPIC30F4013工业级双极步进电机控制方案 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/5 10:28:07
多智能体协作系统架构设计与实践优化 1. 多智能体协作系统的时代背景2017年Transformer架构的诞生彻底改变了人工智能的发展轨迹。当行业还沉浸在单一大模型带来的性能突破时,Anthropic的研究团队已经将目光投向了更前沿的领域——如何让多个智能体通过协作产生超越单体能力的系统智能。这就像交响乐团中… · 2026/11/5 0:00:39
大模型系统性入门实战指南:从原理到部署微调的全链路路线 提到大模型的系统性入门,我先说个结论:这事真不难,难的是资料太散、路线太多,今天这个框架明天那个工具,新人很容易在“收藏夹吃灰”和“教程看到一半放弃”之间反复横跳。市面上关于大模型的内容少说有几十万篇&#… · 2026/11/5 0:00:39
鸿蒙文件系统沙箱机制解析与开发实践 1. 鸿蒙文件系统沙箱机制深度解析作为一名从Android转向鸿蒙开发的工程师,我深刻体会到文件系统访问是迁移过程中最先遇到的"拦路虎"。在Android上运行良好的文件读写代码,在鸿蒙真机环境却频频出现文件写入后神秘消失或直接抛出权限拒绝错误的… · 2026/11/5 0:00:39
双极步进电机控制实战:DRV8818PWPR与PIC18F86K22驱动调试 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/5 10:27:59
STM32F207ZG + DRV8818PWPR 步进电机驱动实战解析 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/5 10:28:03
DRV8818PWPR+dsPIC30F4013工业级双极步进电机控制方案 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/5 10:28:07