数据结构与算法学习笔记----欧拉函数

news2025/1/5 9:47:35

数据结构与算法学习笔记----欧拉函数

@@ author: 明月清了个风
@@ first publish time: 2025.1.1

ps⭐️欧拉函数的定义及求法,第二题是在线性筛法的过程中维护欧拉函数。

欧拉函数

通常用符号 φ ( n ) \varphi(n) φ(n)表示,定义为小于或等于 n n n且与 n n n互质的正整数的个数。

如何求解

n n n的质因数分解为(基于算术基本定理,这里可以看上一篇约数的相关内容):

n = p 1 e 1 p 2 e 2 ⋯ p k e k (1) n=p_{1}^{e_1}p_{2}^{e_2}\cdots p_{k}^{e_k} \tag{1} n=p1e1p2e2pkek(1)

则欧拉函数 φ ( n ) \varphi(n) φ(n)可以通过以下公式计算:

φ ( n ) = n ( 1 − 1 p 1 ) ( 1 − 1 p 2 ) ⋯ ( 1 − 1 p k ) (2) \varphi(n) = n (1 - \frac{1}{p_1}) (1 - \frac{1}{p_2}) \cdots (1 - \frac{1}{p_k}) \tag{2} φ(n)=n(1p11)(1p21)(1pk1)(2)

公式推导

这里给出y总讲解的公式推导,根据容斥原理进行理解。

对于每个质因数 p i p_i pi来说, 1 ∼ n 1 \sim n 1n中有 n p i \frac{n}{p_i} pin个数与 n n n不互斥,这些分别是 p i p_i pi 1 1 1倍, 2 2 2倍…。

那么就要从 n n n中减去这些数,因此有

n − n p 1 − n p 2 − ⋯ − n p k (3) n - \frac{n}{p_1} - \frac{n}{p_2} - \cdots -\frac{n}{p_k} \tag{3} np1np2npkn(3)

但是需要注意的是,在 1 ∼ n 1 \sim n 1n中也会有一些数既是 p i p_i pi的倍数又是 p j p_j pj的倍数,那么这个数就会被减去两次,因此又要加回来,上式变为

n − n p 1 − n p 2 − ⋯ − n p k + ∑ 1 p i p j (4) n - \frac{n}{p_1} - \frac{n}{p_2} - \cdots -\frac{n}{p_k} + \sum \frac{1}{p_i p_j} \tag{4} np1np2npkn+pipj1(4)

以此类推,又会有有的数是三个质因数的倍数,因此又会多加上,所以要再减去

最终就会有

n − n p 1 − n p 2 − ⋯ − n p k + ∑ 1 p i p j − ∑ 1 p i p j p k + ⋯ ± ∑ 1 p i p j ⋯ p k (5) n - \frac{n}{p_1} - \frac{n}{p_2} - \cdots -\frac{n}{p_k} + \sum \frac{1}{p_i p_j} - \sum \frac{1}{p_i p_j p_k} + \cdots \pm \sum \frac{1}{p_i p_j \cdots p_k} \tag{5} np1np2npkn+pipj1pipjpk1+±pipjpk1(5)

即式(2)的展开式。

Acwing 873. 欧拉函数

[原题链接](873. 欧拉函数 - AcWing题库)

给定 n n n个正整数 a i a_i ai,对于每个整数 a i a_i ai,请你求出每个数的欧拉函数。

输入格式

第一行包含整数 n n n

接下来 n n n行,每行包含一个正整数 a i a_i ai

输出格式

输出 n n n行,每行输出一个正整数 a i a_i ai的欧拉函数

数据范围

1 ≤ n ≤ 100 1 \le n \le 100 1n100,

1 ≤ a i ≤ 2 × 1 0 9 1 \le a_i \le 2\times 10^9 1ai2×109

思路

按照上述公式,对每个 a i a_i ai分解质因数即可,然后按式(2)乘起来,注意点是不要有小数,因此要变形一下,先除再乘,具体看代码的实现吧。

代码的时间复杂度瓶颈就在分解质因数这一步,因为要算 n n n次,所以为 O ( n n ) O(n\sqrt{n}) O(nn )

代码

#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>

using namespace std;

int main()
{
    int n;
    cin >> n;
    
    while(n --)
    {
        int a;
        cin >> a;
        
        int res = a;
        for(int i = 2; i <= a / i; i ++)
        {
            if(a % i == 0)  // 分解质因数
            {
                res = res / i * (i - 1);
                while(a % i == 0) a /= i;
            }
        }
        if(a > 1) res = res / a * (a - 1);
        
        cout << res << endl;
    }
    
    return 0;
}

Acwing 874. 筛法求欧拉函数

[原题链接](874. 筛法求欧拉函数 - AcWing题库)

给定一个正整数 n n n,求 1 ∼ n 1 \sim n 1n中每个数的欧拉函数之和。

输入格式

共一行,包含一个整数 n n n

输出格式

共一行,包含一个整数,表示 1 ∼ n 1 \sim n 1n中每个数的欧拉函数之和 。

数据范围

1 ≤ n ≤ 1 0 6 1 \le n \le 10^6 1n106

思路

线性筛选的过程中可以维护欧拉函数,关于线性筛法的讲解可以看这一个链接,这里我们放一个线性筛的代码

int primes[N], cnt;
bool st[N];

void get_primes(int n)
{
    for(int i = 2; i <= n; i ++)
    {
        if(!st[i]) primes[cnt ++] = i;
        for(int j = 0; primes[j] <= n / i; j ++)
        {
            st[i * primes[j]] = true;
            if(i % primes[j] == 0) break;
        }
    }
}

首先根据定义,所有的质数 i i i的欧拉函数是 φ ( i ) = i − 1 \varphi(i) = i - 1 φ(i)=i1,因为 1 ∼ i 1 \sim i 1i中有 i − 1 i - 1 i1个数与质数 i i i自己互质。

在线性筛中,我们会将所有的质数都存在primes[]数组中,对于所有的合数通过st[]数组标记的方式筛选,那么对于这些数来说,有两种情况:1️⃣i %primes[j] != 0;2️⃣i % primes[[j] == 0

  • 线性筛的原则是对于每个非质数,用其最小质因子将其筛除,那么对于第一种情况,primes[j]不是i的质因子且大于i的所有质因子(因为是从小达到枚举的),那么对于数i * primes[j]来说,primes[j]就是其最小质因子,因此这里st[i * primes[j] = true将其筛除,那么其质因数分解就会是i的质因数分解再乘上primes[j],根据欧拉函数的定义,就可以知道其欧拉函数表达式为 φ ( i ∗ p r i m e s [ j ] ) = φ ( i ) ∗ p r i m e s [ j ] ∗ ( 1 − 1 p r i m e s [ j ] ) \varphi(i * primes[j]) = \varphi(i) * primes[j] * (1 - \frac{1}{primes[j]}) φ(iprimes[j])=φ(i)primes[j](1primes[j]1),用代码表示就是phi[i * primes[j] = phi[i] * (primes[j] - 1)
  • 那么对于第二种情况,当i % primes[j] == 0时表示primes[j]i的最小质因子,因此因此其欧拉函数表达式为 φ ( i ∗ p r i m e s [ j ] ) = φ ( i ) ∗ p r i m e s [ j ] \varphi(i * primes[j]) = \varphi(i) * primes[j] φ(iprimes[j])=φ(i)primes[j],用代码表示就是phi[i * primes[j] = phi[i] * primes[j]

代码

#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>

using namespace std;

typedef long long LL;

const int N = 1000010;

int n;
int phi[N];
int primes[N], cnt;
bool st[N];

LL get_eulers(int n)
{
    phi[1] = 1;
    
    for(int i = 2; i <= n; i ++)
    {
        if(!st[i]) primes[cnt ++] = i, phi[i] = i - 1;
        for(int j = 0; primes[j] <= n / i; j ++)
        {
            st[i * primes[j]] = true;
            if(i % primes[j] == 0)
            {
                phi[i * primes[j]] = phi[i] * primes[j];
                break;
            }
            phi[i * primes[j]] = phi[i] * (primes[j] - 1);
        }
    }
    
    LL res = 0;
    for(int i = 1; i <= n; i ++) res += phi[i];
    
    return res;
}

int main()
{
    cin >> n;
    
    cout << get_eulers(n) << endl;
    
    return 0;
}

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Docker 安装与配置 Nginx

摘要 1、本文全面介绍了如何在 Docker 环境中安装和配置 Nginx 容器。 2、文中详细解释了如何设置 HTTPS 安全连接及配置 Nginx 以实现前后端分离的代理服务。 2、同时&#xff0c;探讨了通过 IP 和域名两种方式访问 Nginx 服务的具体配置方法 3、此外&#xff0c;文章还涵…

SpringCloud微服务架构

文章目录 认识微服务&#xff1a;SpringCloud 服务拆分及远程调用实现夸远程服务调用使用RestTemplateEureka注册中心 搭建EruekaServer注册服务服务发现 Ribbon负载均衡 修改负载均衡规则解饿加载 Nacos注册中心&#xff08;nacos一部分功能&#xff09; 服务注册到nacosnacos…

WireShark4.4.2浏览器网络调试指南:TCP传输包分析(七)

概述 在使用Wireshark进行网络分析时&#xff0c;理解每一个数据包的组成部分对于网络分析非常重要。特别是在TCP协议中的“三次握手”过程中&#xff0c;每个数据包会包含多个层次的信息&#xff0c;从帧信息到TCP协议的详细内容。下面是对TCP握手过程中第一个SYN数据包的详细…

kafka使用常见问题

连接不上kafka,报下边的错 org.apache.kafka.common.KafkaException: Producer is closed forcefully.at org.apache.kafka.clients.producer.internals.RecordAccumulator.abortBatches(RecordAccumulator.java:760) [kafka-clients-3.0.2.jar:na]at org.apache.kafka.client…

用uniapp写一个播放视频首页页面代码

效果如下图所示 首页有导航栏&#xff0c;搜索框&#xff0c;和视频列表&#xff0c; 导航栏如下图 搜索框如下图 视频列表如下图 文件目录 视频首页页面代码如下 <template> <view class"video-home"> <!-- 搜索栏 --> <view class…

深入浅出:从入门到精通大模型Prompt、SFT、RAG、Infer、Deploy、Agent

阅读原文 渐入佳境 我们都知道&#xff0c;通过编写一个提示词&#xff08;prompt&#xff09;&#xff0c;我们可以引导大模型生成回答&#xff0c;从而开启愉快的人工智能对话&#xff0c;比如让模型介绍一下卡皮巴拉。上边简图描述了这个过程&#xff0c;我们拆成两部分 pr…

Unity-Mirror网络框架-从入门到精通之Basic示例

文章目录 前言Basic示例场景元素预制体元素代码逻辑BasicNetManagerPlayer逻辑SyncVars属性Server逻辑Client逻辑 PlayerUI逻辑 最后 前言 在现代游戏开发中&#xff0c;网络功能日益成为提升游戏体验的关键组成部分。Mirror是一个用于Unity的开源网络框架&#xff0c;专为多人…

【新方法】通过清华镜像源加速 PyTorch GPU 2.5安装及 CUDA 版本选择指南

下面详细介绍所提到的两条命令&#xff0c;它们的作用及如何在你的 Python 环境中加速 PyTorch 等库的安装。 1. 设置清华镜像源 pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple这条命令的作用是将 pip &#xff08;Python 的包管理工具&#xf…

自动化测试-Pytest测试

目录 pytest简介 基本测试实例 编写测试文件 执行测试 pytest运行时参数 mark标记 Fixture pytest插件 Allure测试报告 测试步骤 pytest简介 Pytest‌是一个非常流行的Python测试框架&#xff0c;它支持简单的单元测试和复杂的功能测试&#xff0c;具有易于上手、功…

Java-33 深入浅出 Spring - FactoryBean 和 BeanFactory BeanPostProcessor

点一下关注吧&#xff01;&#xff01;&#xff01;非常感谢&#xff01;&#xff01;持续更新&#xff01;&#xff01;&#xff01; 大数据篇正在更新&#xff01;https://blog.csdn.net/w776341482/category_12713819.html 目前已经更新到了&#xff1a; MyBatis&#xff…

MySQL 服务器简介

通常所说的 MySQL 服务器指的是mysqld程序&#xff0c;当运⾏mysqld后对外提供MySQL 服务&#xff0c;这个专题的内容涵盖了以下关于MySQL 服务器以及相关配置的内容&#xff0c;包括&#xff1a; 服务器⽀持的启动选项。可以在命令⾏和配置⽂件中指定这些选项。 服务器系统变…

分布式版本管理工具——Git关联远程仓库(github+gitee)

Git远程仓库&#xff08;Github&#xff09;的基本使用 一、前言二、Git远程仓库介绍三、演示1. 关联github远程仓库2. 关联gitee&#xff08;码云&#xff09;远程仓库3. 重命名远程仓库名4. 移除远程仓库 四、结束语 一、前言 古之立大事者&#xff0c;不惟有超世之才&#x…

ZLib库使用详细教程 以及标准ZLib函数和QT自带压缩函数比较

1. 下载Zlib 官网下载地址如下&#xff1a;http://www.zlib.net/ 2. 利用cmake编译zlib 有两种方法可以打开cmake-gui winR输入cmd打开命令行&#xff0c;在命令行中输入cmake-gui可以直接打开应用界面找到你一开始安装cmake的文件夹&#xff0c;在bin子文件夹中双击cmake-…

加载Tokenizer和基础模型的解析及文件介绍:from_pretrained到底加载了什么?

加载Tokenizer和基础模型的解析及文件介绍 在使用Hugging Face的transformers库加载Tokenizer和基础模型时&#xff0c;涉及到许多文件的调用和解析。这篇博客将详细介绍这些文件的功能和它们在加载过程中的作用&#xff0c;同时结合代码片段进行解析。 下图是我本地下载好模…

SpringAI从入门到熟练

学习SpringAI的记录情况 文章目录 前言 因公司需要故而学习SpringAI文档&#xff0c;故将自己所见所想写成文章&#xff0c;供大佬们参考 主要是为什么这么写呢&#xff0c;为何不抽出来呢&#xff0c;还是希望可以用的时候更加方便一点&#xff0c;如果大家有需求可以自行去…

嵌入式系统中C++的基本使用方法

大家好,今天主要给大家分享一下,最近操作C++代码的控制方法。 什么是构造函数?构造函数在对象实例化时被系统自动调用,仅且调用一次。 什么是析构函数?与构造函数相反, 在对象结束其生命周期时系统自动执行析构函数。 第一个:析构函数与构造函数区别 实例代码: #inclu…

【Qt】多元素控件:QListWidget、QTableWidget、QTreeWidget

目录 QListWidget 核心属性&#xff1a; 核心方法&#xff1a; 核心信号&#xff1a; 例子&#xff1a; QListWidgetItem QTableWidget 核心方法&#xff1a; 核心信号 QTableWidgetItem 例子&#xff1a; QTreeWidget 核心方法&#xff1a; 核心信号&#xff1a…

HTML5 标签输入框(Tag Input)详解

HTML5 标签输入框&#xff08;Tag Input&#xff09;详解 标签输入框&#xff08;Tag Input&#xff09;是一种用户界面元素&#xff0c;允许用户输入多个标签或关键词&#xff0c;通常用于表单、搜索框或内容分类等场景。以下是实现标签输入框的详细讲解。 1. 任务概述 标…

前端加载自己制作的栅格切片服务充当底图

注意mapview的center属性和tilelayer.fullExtent的区别。 前者是设置mapview显示的中心点坐标&#xff0c; const view new MapView({ container: "viewDiv", map: map, center:[100,25] }); 后者是读…

Windows 安装Mysql 8.1.0版本,并迁移数据库

一、下载MySQL压缩包 进入MySQL官网&#xff1a;https://downloads.mysql.com/archives/community/ 下载zip包到本地&#xff0c;然后解压缩。 二、安装MySQL 1、 创建my.ini文件 新创建一个my.ini文件&#xff0c;文件内容如下&#xff0c;记得修改【basedir】和【datadir…