欧拉筛法寻找素数与计算欧拉函数求和

欧拉筛法寻找素数与计算欧拉函数求和

  • 一、欧拉函数
    • 1.1定义
    • 1.2性质
    • 1.3唯一分解定理(算术基本定理)
  • 二、Eratosthenes筛法寻找素数
  • 三、欧拉筛法寻找素数
    • 3.1算法代码
    • 3.2算法分析
      • 3.2.1时间复杂度分析(对合数进行不重复筛选)
      • 3.2.2算法正确性分析(对合数进行完全筛选)
    • 3.3与Eratosthenes法实际运行时间对比
  • 四、欧拉筛法计算欧拉函数求和
    • 4.1欧拉函数求和代码
    • 4.2代码改进
      • 4.2.1使用vector类型数组
      • 4.2.2优化数组使用
  • 参考文档

一、欧拉函数

1.1定义

1~n中与n互质的数的个数被称为欧拉函数(记作 phi[n]),例如1 ~ 6中与6互质的数有1,5,所以phi[6]=2。规定phi[1]=1。

1.2性质

  1. m = m 1 m 2 m=m_{1}m_{2} m=m1m2,若 m 1 m_{1} m1与m的所有素因数都相同,则phi[m]= m 2 m_{2} m2×phi[ m 1 m_{1} m1]
  2. m = m 1 m 2 m=m_{1}m_{2} m=m1m2,若 m 1 m_{1} m1 m 2 m_{2} m2互质,则phi[m]=phi[ m 1 m_{1} m1]×phi[ m 2 m_{2} m2]
  3. 若m为素数,则phi[m]=m-1

1.3唯一分解定理(算术基本定理)

设整数a≥2,则a一定可以表示为素数的乘积,即 a = p 1 p 2 . . . p s a=p_{1}p_{2}...p_{s} a=p1p2...ps p s p_{s} ps是素数。

二、Eratosthenes筛法寻找素数

Eratosthenes筛法寻找素数的原理及步骤为:

  1. 根据唯一分解定理可推论出:对于整数n,一定有素因数p< n \sqrt{n} n
  2. 首先筛选出1~ N \sqrt{N} N 范围内的素数,这些素数的整数倍一定是合数,除去这些合数外,剩下的就是1-N范围内的素数。

Eratosthenes筛法算法复杂度为O(NloglogN),代码如下:

unsigned eratosthenes(unsigned upL)
{
	unsigned isprime[upL + 1] = {0};
	unsigned m = sqrt(upL + 0.5);
	for(unsigned i = 2 ; i <= m; i++)
	{
		if(!isprime[i])
		{
			for(unsigned j = i * i; j <= upL; j+=i)
			{
				isprime[j] = 1;
			}
		}
	}
	return 0;
}

三、欧拉筛法寻找素数

3.1算法代码

欧拉筛法寻找素数算法复杂度为O(N),相较于Eratosthenes筛法时间复杂度大幅度降低,但是也更难理解,先给出代码如下:

unsigned euler(unsigned upL)
{
	unsigned n = 0;
	unsigned prime[upL + 1] = {0}, isprime[upL + 1] = {0};
	for(unsigned i = 2 ; i <= upL; i++)
	{
		if(!isprime[i]) prime[++n] = i;
		for(unsigned j = 1; j <= n && i * prime[j] <= upL; j++)
		{
			isprime[prime[j] * i] = 1;
			if(i % prime[j] == 0) break;
		}
	}
	return 0;
}

3.2算法分析

3.2.1时间复杂度分析(对合数进行不重复筛选)

欧拉筛法求解思路与Eratosthenes筛法类似,都为先筛选出素数与合数,然后根据欧拉函数性质求和

代码中筛选素数与合数的部分使用双重循环,但不会对合数进行重复筛选,此处关键代码为if(i % prime[j] == 0) break;,分析如下:

  1. 如果i除以prime[j]等于0,则说明i的其中一个素因数为prime[j],设i=prime[j] * a;
  2. 而此时若不跳出对j的循环继续执行,则j++,i * prime[j+1]=prime[j] * prime[j+1] * a,prime[j+1] * a大于i,在以后对i的循环中必会重复遇到此合数,所以在此时跳出循环,控制程序只对合数筛选一次;
  3. 举例说明,当i=4时,4%2==0时,如不跳出内层循环,则下一次内循环会标记4 * 3=12为合数,而之后当i=6时,6*2=12又会被重复标记。

3.2.2算法正确性分析(对合数进行完全筛选)

对合数筛选的过程中是否会漏掉合数,分析如下:

  1. 根据唯一分解定理,任一合数m必然可以表示为素因数乘积的形式,设其中最小的素因数为p,则m可以表示为m=p*q;
  2. q一定≥p,否则m的最小素因数就不是p,当i循环到q时,素因数p一定被添加至prime数组中,m被标记为合数。

3.3与Eratosthenes法实际运行时间对比

经过多次测试,Eratosthenes法约为1ms,而欧拉法约为2ms,运行截图如下:

在这里插入图片描述
在这里插入图片描述
实际与理论相悖的原因可能是:欧拉法在筛选合数的同时需要操作一个额外的存储素数数组,造成了一定的运行时间浪费。

四、欧拉筛法计算欧拉函数求和

4.1欧拉函数求和代码

欧拉筛法计算欧拉函数与欧拉筛法寻找素数算法一脉相承,主要是利用前文介绍的欧拉函数的性质,在寻找素数的同时计算欧拉函数,在掌握了欧拉筛法寻找素数算法后,会对本小节算法一目了然,代码如下:

unsigned euler_sum(unsigned upL)
{
	unsigned n = 0;
	unsigned phi[upL + 1] = {0}, prime[upL + 1] = {0}, isprime[upL + 1] = {0};
	phi[1] = 1;
	unsigned res = 0;
	for(unsigned i = 2 ; i <= upL; i++)
	{
		if(!isprime[i]) prime[++n] = i, phi[i] = i - 1;
		for(unsigned j = 1; j <= n && i * prime[j] <= upL; j++)
		{
			isprime[prime[j] * i] = 1;
			if(i % prime[j] == 0)
			{
				phi[i * prime[j]] = phi[i] * prime[j];
				break;
			}
			else
			{
				phi[i * prime[j]] = phi[i] * (prime[j] - 1);
			}
		}
		//cout<<i<<','<<phi[upL]<<endl;
	}
	//cout<<phi[upL]<<endl;
	for(unsigned i = 1 ; i <= upL; i ++) res += phi[i];
	return res;
}

欧拉筛法求解欧拉函数求和,算法复杂度同样为O(N)

4.2代码改进

4.1节给出的代码中在栈空间上定义了phi, prime, isprime三个数组,当输入的数较大时,可能会由于栈内存溢出而无法正确运行,有两种方法进行改进,第一种是使用vector类型数组,第二种是改进代码,将prime, isprime两个数组合并为一个数组,下面分别进行介绍。

4.2.1使用vector类型数组

vector是C++标准库中的容器,在堆上分配内存,并且自动管理内存的分配和释放,确保不会发生内存泄漏,代码如下:

unsigned euler_sum(unsigned upL)
{
	unsigned n = 0;
	vector<unsigned> phi(upL + 1), prime(upL + 1), isprime(upL + 1);
	phi[1] = 1;
	unsigned res = 0;
	for(unsigned i = 2 ; i <= upL; i++)
	{
		if(!isprime[i]) prime[++n] = i, phi[i] = i - 1;
		for(unsigned j = 1; j <= n && i * prime[j] <= upL; j++)
		{
			isprime[prime[j] * i] = 1;
			if(i % prime[j] == 0)
			{
				phi[i * prime[j]] = phi[i] * prime[j];
				break;
			}
			else
			{
				phi[i * prime[j]] = phi[i] * (prime[j] - 1);
			}
		}
		//cout<<i<<','<<phi[upL]<<endl;
	}
	//cout<<phi[upL]<<endl;
	for(unsigned i = 1 ; i <= upL; i ++) res += phi[i];
	return res;

上述代码只在三个数组定义处进行更改,其余地方未变。

4.2.2优化数组使用

由于1~N范围内的素数个数一定小于N,那么可以将prime, isprime两个数组合并,代码如下:

unsigned euler_sum(unsigned upL)
{
	unsigned n = 0;
	unsigned phi[upL + 1] = {0}, prime[upL + 1] = {0};
	phi[1] = 1;
	unsigned res = 0;
	for(unsigned i = 2 ; i <= upL; i++)
	{
		if(!prime[i]) prime[++n] = i, phi[i] = i - 1;
		for(unsigned j = 1; j <= n && i * prime[j] <= upL; j++)
		{
			prime[prime[j] * i] = 1;
			if(i % prime[j] == 0)
			{
				phi[i * prime[j]] = phi[i] * prime[j];
				break;
			}
			else
			{
				phi[i * prime[j]] = phi[i] * (prime[j] - 1);
			}
		}
		//cout<<i<<','<<phi[upL]<<endl;
	}
	//cout<<phi[upL]<<endl;
	for(unsigned i = 1 ; i <= upL; i ++) res += phi[i];
	return res;
}

此算法可以显著降低内存占用,降低空间复杂度。

参考文档

初等数论(潘承洞 潘承彪)
C++程序设计竞赛真题实战特训教程
算法竞赛入门经典(第2版) (刘汝佳)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/976190.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

VScode 开发

目录 安装 VS Code 创建一个 Python 代码文件 安装 VS Code VSCode&#xff08;全称&#xff1a;Visual Studio Code&#xff09;是一款由微软开发且跨平台的免费源代码编辑器&#xff0c;VSCode 开发环境非常简单易用。 VSCode 安装也很简单&#xff0c;打开官网 Visual S…

政安晨【零基础玩转各类开源AI项目】DeepSeek 多模态大模型Janus-Pro-7B,本地部署!支持图像识别和图像生成

政安晨的个人主页&#xff1a;政安晨 欢迎 &#x1f44d;点赞✍评论⭐收藏 希望政安晨的博客能够对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出指正&#xff01; 目录 下载项目 创建虚拟环境 安装项目依赖 安装 Gradio&#xff08;UI&#xff09; 运…

开发 picgo-plugin-huawei 插件,解决华为云社区外链限制问题

开发 picgo-plugin-huawei 插件&#xff0c;解决华为云社区外链限制问题 在技术博客平台中&#xff0c;外链的使用常常受到限制&#xff0c;这给我们的写作和内容展示带来了一定的不便。为了应对这一问题&#xff0c;我开发了 picgo-plugin-huawei 插件&#xff0c;它能够有效…

QT 基础知识点

1.基础窗口类QMainWindow qDialog Qwidget 随项目一起创建的窗口基类有三个可选QMainWindow qDialog Qwidget 1.1 Qwidget 是所有窗口的基类&#xff0c;只要是他的子类&#xff0c;或子类的子类&#xff0c;都具有他的属性。 右键项目 Add New -> Qt qt设计师界面类&am…

【OMCI实践】ONT上线过程的omci消息(五)

引言 在前四篇文章中&#xff0c;主要介绍了ONT上线过程的OMCI交互的第一、二、三个阶段omci消息&#xff0c;本篇介绍第四个阶段&#xff0c;OLT下发配置到ONT。前三个阶段&#xff0c;每个厂商OLT和ONT都遵循相同标准&#xff0c;OMCI的交换过程大同小异。但第四个阶段&…

WebXR教学 02 配置开发环境

默认操作系统为Windows 1.VS Code VS Code 是一款轻量级、功能强大的代码编辑器&#xff0c;适用于多种编程语言。 下载 步骤 1&#xff1a;访问 VS Code 官方网站 打开浏览器&#xff08;如 Chrome、Edge 等&#xff09;。 在地址栏输入以下网址&#xff1a; https://code.v…

云计算及其他计算

云计算知识思维导图&#xff1a;https://kdocs.cn/l/cpl2Kizx7IyC 云计算的核心判断标准通常基于美国国家标准与技术研究院&#xff08;NIST&#xff09;的定义&#xff0c;并结合实际应用场景。以下是判断一个服务是否为云计算的关键标准&#xff0c;以及对应的服务类型&#…

记录首次安装远古时代所需的运行环境成功npm install --save-dev node-sass

最开始的报错&#xff1a; 最后根据报错一步步 安装所需要的pythong之类的环境&#xff0c;最后终于成功了&#xff0c;得以让我在github上拉的vuehr项目&#xff08;狗头18年还是20年的远古项目&#xff09;成功本地运行&#xff0c;最后附上本地运行成功的贴图。如果大家也在…

WordPress Elementor提示错误无法保存500的解决指南

500内部服务器错误是一种常见的服务器错误&#xff0c;通常由网站的服务器环境引起。这种错误可能导致网站无法正常访问&#xff0c;影响用户体验。本文将探讨500错误的常见原因&#xff0c;并提供解决方案&#xff0c;特别针对使用Elementor构建的WordPress网站。 500错误的常…

DeepSeek写俄罗斯方块手机小游戏

DeepSeek写俄罗斯方块手机小游戏 提问 根据提的要求&#xff0c;让DeepSeek整理的需求&#xff0c;进行提问&#xff0c;内容如下&#xff1a; 请生成一个包含以下功能的可运行移动端俄罗斯方块H5文件&#xff1a; 核心功能要求 原生JavaScript实现&#xff0c;适配手机屏幕 …

题解:洛谷 P11785 「FAOI-R4」手写的从前

题目https://www.luogu.com.cn/problem/P11785赛时写出来的&#xff0c;可惜报名晚了一些&#xff08;大概 1h&#xff09;&#xff0c;卡在第 363 名。 首先&#xff0c;我们对 进行二进制拆分&#xff0c;拆成若干个二的幂相加的形式。 随后&#xff0c;如果这个序列的长度…

【无人集群系列---无人机集群编队算法】

【无人集群系列---无人机集群编队算法】 一、核心目标二、主流编队控制方法1. 领航-跟随法&#xff08;Leader-Follower&#xff09;2. 虚拟结构法&#xff08;Virtual Structure&#xff09;3. 行为法&#xff08;Behavior-Based&#xff09;4. 人工势场法&#xff08;Artific…

Linux项目自动化构建工具-make/Makefile (linux第六课)

目录 背景 介绍 依赖关系的格式 依赖方法的格式 原理 背景 会不会写makefile&#xff0c;从一个侧面说明了一个人是否具备完成大型工程的能力一个工程中的源文件不计数&#xff0c;其按类型、功能、模块分别放在若干个目录中&#xff0c;makefile定义了一系列的规则来指定…

【基于SprintBoot+Mybatis+Mysql】电脑商城项目之加入购物车和显示购物车列表

&#x1f9f8;安清h&#xff1a;个人主页 &#x1f3a5;个人专栏&#xff1a;【Spring篇】【计算机网络】【Mybatis篇】 &#x1f6a6;作者简介&#xff1a;一个有趣爱睡觉的intp&#xff0c;期待和更多人分享自己所学知识的真诚大学生。 目录 &#x1f680;1.加入购物车-数…

嵌入式项目:STM32刷卡指纹智能门禁系统

本文详细介绍基于STM32的刷卡指纹智能门禁系统。 获取资料/指导答疑/技术交流/选题/帮助&#xff0c;请点链接&#xff1a; https://gitee.com/zengzhaorong/share_contact/blob/master/stm32.txt 1 系统功能 1.1 功能概述 本系统由STM32硬件端&#xff08;下位机&#xff09;…

短剧小程序系统源码

短剧小程序系统源码 今天我要向大家介绍的是最新作品——短剧小程序系统源码。这不仅仅是一款简单的播放工具&#xff0c;它背后蕴含的强大功能能够帮助你的短剧业务实现质的飞跃&#xff01; 为什么说这款源码很厉害&#xff1f; 首先&#xff0c;在当今竞争激烈的市场环境…

Ubuntu中 json 打包数据的使用

1.JSON的概念和作用 为了避免不同平台下的字节对齐、类型大小不统一的问题&#xff0c;json库把数据封装成具有一定格式的字符流数据&#xff0c;进行传输。json格式&#xff1a;把数据与键值一一对应&#xff0c;数据传输双方约定好同一键值&#xff0c;使用接口API根据键值操…

网页制作08-html,css,javascript初认识のhtml使用框架结构,请先建立站点!

框架一般由框架集和框架组成。 框架集就像一个大的容器&#xff0c;包括所有的框架&#xff0c;是框架的集合。 框架是框架集中一个独立的区域用于显示一个独立的网页文档。 框架集是文件html&#xff0c;它定义一组框架的布局和属性&#xff0c;包括框架的数目&#xff0c;框架…

应无所住而生其心:心灵的自在与解脱

在快节奏、高压力的现代社会中&#xff0c;人们常常感到心灵被各种琐事和追求所束缚。如何找到内心的平静与自由&#xff0c;成为了许多人寻求的答案。“应无所住而生其心”这一出自《金刚经》的理念&#xff0c;为我们提供了一条通往心灵解放的道路。 一、核心含义 “应无所…