CSP-J基础之数学基础 初等数论 一篇搞懂(二)

2024-09-08 10:20

本文主要是介绍CSP-J基础之数学基础 初等数论 一篇搞懂(二),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

  • 前言
  • 算术基本定理简介
    • 什么是质数?
    • 举个简单例子:
    • 重要的结论:
    • 算术基本定理公式
      • 解释:
      • 举例:
    • 算术基本定理的求法
      • 如何找出质因数:
      • 举个简单的例子:
    • 重要的步骤:
    • C++实现
  • 同余
    • 举个例子:
    • 同余的性质简介
      • 1. 同余的自反性
      • 2. 同余的对称性
      • 3. 同余的传递性
      • 4. 同余的加法性质
      • 5. 同余的乘法性质
    • 推论
  • 总结


前言

在计算机科学和数学中,初等数论是一个重要的基础领域,涉及到整数的性质和运算。掌握初等数论的基本概念对于解决很多数学和编程问题至关重要。本篇文章旨在深入探讨初等数论中的几个核心主题,帮助读者更好地理解和运用这些基础知识。通过对同余、质数及其性质、以及相关算法的详细讲解,我们将展示如何利用这些数学工具解决实际问题。本文的目标是使读者对初等数论有一个全面而清晰的认识,为进一步的数学学习和编程实践奠定坚实的基础。


算术基本定理简介

算术基本定理其实很简单,主要讲的是每一个大于1的整数都可以拆分成一堆质数的乘积,而且这种拆分方式是唯一的,尽管质数的顺序可以不同。

什么是质数?

质数是只能被1和它自己整除的数。比如,2、3、5、7都是质数。

举个简单例子:

例子 1:

  • 12 是一个大于 1 的数。
  • 你可以把 12 拆成 2 × 2 × 3。
  • 这里的 2 和 3 都是质数。
  • 不管你怎么排列这三个数,结果都是 12。
  • 所以,12 的质因数分解是 2 × 2 × 3,这就是它唯一的拆分方法(质数的顺序不算)。

例子 2:

  • 30 是另一个数。
  • 你可以把 30 拆成 2 × 3 × 5。
  • 2、3 和 5 都是质数。
  • 这就是 30 的唯一质因数分解方式。

重要的结论:

每个大于1的整数都有这样一种唯一的质数分解,虽然质数的顺序可以不同,但它们的组合方式是唯一的。这就像每个人的身份证号码都是唯一的一样,质数分解也有它自己独特的方式。

通过这个定理,我们可以把复杂的数变得简单,方便我们做各种计算和解决问题。

算术基本定理公式

算术基本定理的公式可以简洁地表述为:

每一个大于1的整数 ( n ) 都可以唯一地表示为若干个质数的乘积,形式为:

在这里插入图片描述

其中:

  • 在这里插入图片描述
    是质数(它们彼此不同)。
  • 在这里插入图片描述
    是正整数,表示每个质数的指数(即质数在分解中出现的次数)。

解释:

  1. 质数:每一个质数 ( p_i ) 是只能被1和它本身整除的数。
  2. 指数:( e_i ) 表示质数 ( p_i ) 在分解中的次数。

举例:

例子 1:

  • 对于整数 60,其质因数分解为:
    在这里插入图片描述

    • 质数 2 的指数是 2。
    • 质数 3 的指数是 1。
    • 质数 5 的指数是 1。

例子 2:

  • 对于整数 84,其质因数分解为:
    在这里插入图片描述

    • 质数 2 的指数是 2。
    • 质数 3 的指数是 1。
    • 质数 7 的指数是 1。

这些公式和表示法保证了每个大于1的整数都有唯一的质因数分解方式,尽管质数的顺序可以不同。

算术基本定理的求法

算术基本定理告诉我们,每个大于1的整数都可以用一堆质数的乘积来表示。现在我们来看看怎么找到这些质数,简单来说,就是把一个数拆解成它的质数“积木”。

如何找出质因数:

  1. 找到最小的质数:从2开始,检查这个数能否被2整除(能整除就是说明2是它的质因数)。

  2. 不断分解

    • 如果能整除,就把这个数除以这个质数,记下这个质数。
    • 继续用结果去尝试能否被2整除。直到不能被2整除为止,然后换下一个质数(即3)。
  3. 重复这个过程,直到你得到的数是1为止。所有能整除的质数和它们的“重复次数”就是这个数的质因数分解。

举个简单的例子:

找出 30 的质因数分解:

  1. 从2开始

    • 30 能被2整除(30 ÷ 2 = 15)。所以2是30的一个质因数。现在我们得到的数是15。
  2. 用15去检查

    • 15 不能被2整除,换下一个质数3。
    • 15 能被3整除(15 ÷ 3 = 5)。所以3是30的另一个质因数。现在我们得到的数是5。
  3. 用5去检查

    • 5 不能被3整除,换下一个质数5。
    • 5 能被5整除(5 ÷ 5 = 1)。所以5是30的质因数。现在我们得到的数是1,分解完毕。
  4. 总结

    • 30 = 2 × 3 × 5

所以,30 的质因数分解是 2 × 3 × 5。

重要的步骤:

  1. 从最小的质数开始试
  2. 不断除,直到不能再除下去。
  3. 记录每个质数和它出现的次数,直到结果是1。

这样你就能把任何大于1的整数拆解成质数的“积木”了!

C++实现

根据上面的算术基本定理求法,可得下面的函数

// 质因数分解函数
void primeFactorization(int n) {// 从最小质数2开始int divisor = 2;// 处理每个可能的质因数while (n > 1) {int count = 0;// 如果当前质数能整除n,则记录并继续除while (n % divisor == 0) {n /= divisor;count++;}// 如果当前质数有出现if (count > 0) {printf("%d^%d ", divisor, count);}// 继续检查下一个质数divisor++;}printf("\n");
}

或者这个更加简单与简洁:

#include<bits/stdc++.h>
using namespace std;
void dfs(int n, int p){if(n==1) return;if(n%p == 0){cout << p <<" ";dfs(n/p,p); }else{dfs(n,p+1); }
}

同余

什么是同余?

同余听起来可能有点复杂,但其实它很简单。可以把它想象成“余数相同”的意思。

简单的解释:

想象你有几个数字,比如 15 和 7。我们要检查它们的“余数”是否一样。余数就是你用一个数字去除另一个数字时,剩下的那部分。

  • 比如,你用 15 除以 7,商是 2,余数是 1(因为 15 = 7 × 2 + 1)。
  • 然后,你用 7 除以 7,商是 1,余数是 0(因为 7 = 7 × 1 + 0)。

在这种情况下,我们关注的是 15 和 7 的余数部分。当两个数除以同一个数时,如果它们的余数是一样的,我们就说这两个数是同余的

举个例子:

例子 1:

  • 15 除以 7 余数是 1。
  • 22 除以 7 余数也是 1(因为 22 = 7 × 3 + 1)。

所以,我们说 15 和 22 对 7 同余。我们可以写作:
在这里插入图片描述

例子 2:

  • 10 除以 4 余数是 2。
  • 22 除以 4 余数也是 2(因为 22 = 4 × 5 + 2)。

所以,10 和 22 对 4 同余。我们可以写作:
在这里插入图片描述

总结:

同余就是看两个数在除以另一个数时,是否剩下相同的余数。如果它们的余数一样,我们就说这两个数对这个数是同余的。这个概念在很多数学问题和计算中都很有用,帮助我们处理和比较数字的余数部分。

同余的性质简介

同余有几个基本的“规律”或者“规则”,这些规则帮助我们在做数学题时简化问题。我们可以把这些性质看作是同余的“操作指南”。

1. 同余的自反性

性质: 一个数和它自己在任何模数下都是同余的。

通俗说法: 自己和自己肯定是一样的,所以它们的余数也是一样的。

示例:
在这里插入图片描述

2. 同余的对称性

性质: 如果一个数 (a) 在模 (m) 下和数 (b) 是同余的,那么 (b) 在模 (m) 下也和 (a) 是同余的。

通俗说法: 如果你和你的朋友穿了一样的衣服,你的朋友也和你穿了一样的衣服。

示例:
如果 在这里插入图片描述
,那么也有 在这里插入图片描述

3. 同余的传递性

性质: 如果 (a) 在模 (m) 下和 (b) 是同余的,且 (b) 在模 (m) 下和 (c) 是同余的,那么 (a) 在模 (m) 下也和 (c) 是同余的。

通俗说法: 如果你和你朋友穿了一样的衣服,你朋友和另一个朋友穿了一样的衣服,那么你和另一个朋友也穿了一样的衣服。

示例:
如果 在这里插入图片描述
,那么 在这里插入图片描述

4. 同余的加法性质

性质: 如果 (a) 在模 (m) 下和 (b) 是同余的,(c) 在模 (m) 下和 (d) 是同余的,那么 (a + c) 在模 (m) 下和 (b + d) 是同余的。

通俗说法: 如果你和朋友的衣服一样,你们加上两个相同的饰品,还是会穿得一样。

示例:
如果 在这里插入图片描述
在这里插入图片描述
,那么 在这里插入图片描述

5. 同余的乘法性质

性质: 如果 (a) 在模 (m) 下和 (b) 是同余的,(c) 在模 (m) 下和 (d) 是同余的,那么 (a \times c) 在模 (m) 下和 (b \times d) 是同余的。

通俗说法: 如果你和朋友穿了一样的衣服,朋友和另一个人也穿了一样的衣服,你们三个人的组合也一样。

示例:
如果 在这里插入图片描述
,那么在这里插入图片描述

总结:

同余的这些性质帮助我们在数学中简化计算和推理,就像是给我们一个“操作指南”,让我们能够更容易地处理和比较数的余数。通过这些性质,我们可以更加灵活地解决问题和进行计算。

推论

对于加法、乘法、乘方运算,算好后取余和边算边取余是等价的
在计算中,尤其是在处理大数和数学问题时,“先算好再取余”和“边算边取余” 的等价性非常有用。它可以帮助我们简化计算、提高效率,并且在许多应用场景中发挥作用。下面是这些等价性的应用和解释:

  1. 简化计算

先算好再取余 vs 边算边取余

  • 先算好再取余:先进行完整的加法、乘法或乘方运算,然后再对结果取模。
  • 边算边取余:在进行加法、乘法或乘方运算的过程中,每一步都取模,以保持计算结果在一个较小的范围内。

应用示例:

  • 计算大数的余数
    在处理大数时,直接计算可能会非常庞大,无法存储或处理。边算边取余可以确保每一步计算结果不会超出机器的存储能力。例如,计算 ( (2^{100} + 3^{100}) \mod 7 ) 时,可以逐步取模,避免处理非常大的数字。
  1. 提高计算效率
  • 避免大数溢出
    边算边取余可以防止数值过大导致的溢出问题。在程序中,当进行连续的运算时,保持中间结果的小范围可以避免计算机无法处理的情况。

应用示例:

  • 大数模运算
    在编程中进行模运算,尤其是涉及到加法、乘法和乘方时,边算边取余可以提高效率并避免溢出。比如,计算 ( (a \times b) \mod m ) 可以写成 ( [(a \mod m) \times (b \mod m)] \mod m )。
  1. 密码学
  • 大数运算
    密码学中的很多算法(如RSA算法)涉及到大数运算。边算边取余可以优化这些运算,确保计算过程高效且不会因为数值过大而出现问题。

应用示例:

  • RSA加密算法
    在RSA加密中,我们需要对非常大的数字进行取模操作。边算边取余可以加快计算速度,并且保证运算在一个可以管理的范围内。
  1. 计算机算法
  • 优化算法
    在一些计算密集型算法中,边算边取余可以减少计算量并提高算法性能。例如,在处理矩阵运算时,可以在每一步中应用取模,减少数据量,提高计算速度。

应用示例:

  • 快速幂算法
    快速幂算法用来计算 ( a^b \mod m )。边算边取余可以大大提高计算效率,通过不断取模,保持结果在一个较小的范围内。
  1. 图论
  • 路径计算
    在图论中,计算最短路径或其他路径相关问题时,边算边取余可以确保路径计算不会因数字过大而变得复杂或效率低下。

应用示例:

  • 最短路径算法
    在求解最短路径问题时,可以在每一步运算中取模,防止路径长度过大。

边算边取余和先算好再取余是等价的,但在实际应用中,边算边取余常常更有优势。它帮助我们避免大数计算中的溢出问题,提高计算效率,尤其是在涉及大数和复杂计算的场景中,如密码学、计算机算法和图论等领域。


总结

初等数论的学习不仅仅是对数学概念的掌握,更是对这些概念在实际问题中应用的理解。从同余的基本性质到质数的分解,这些数学工具帮助我们在计算机科学、加密算法以及其他技术领域中解决复杂问题。通过对这些基本理论的深入学习,我们能够更好地理解数据处理、算法优化以及数学建模等方面的实际应用。掌握初等数论的核心知识,将为我们的数学思维和编程能力提供强有力的支持,推动我们在相关领域的进一步探索和发展。

这篇关于CSP-J基础之数学基础 初等数论 一篇搞懂(二)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1147846

相关文章

【数据结构】——原来排序算法搞懂这些就行,轻松拿捏

前言:快速排序的实现最重要的是找基准值,下面让我们来了解如何实现找基准值 基准值的注释:在快排的过程中,每一次我们要取一个元素作为枢纽值,以这个数字来将序列划分为两部分。 在此我们采用三数取中法,也就是取左端、中间、右端三个数,然后进行排序,将中间数作为枢纽值。 快速排序实现主框架: //快速排序 void QuickSort(int* arr, int left, int rig

零基础学习Redis(10) -- zset类型命令使用

zset是有序集合,内部除了存储元素外,还会存储一个score,存储在zset中的元素会按照score的大小升序排列,不同元素的score可以重复,score相同的元素会按照元素的字典序排列。 1. zset常用命令 1.1 zadd  zadd key [NX | XX] [GT | LT]   [CH] [INCR] score member [score member ...]

uva 10014 Simple calculations(数学推导)

直接按照题意来推导最后的结果就行了。 开始的时候只做到了第一个推导,第二次没有继续下去。 代码: #include<stdio.h>int main(){int T, n, i;double a, aa, sum, temp, ans;scanf("%d", &T);while(T--){scanf("%d", &n);scanf("%lf", &first);scanf

uva 10025 The ? 1 ? 2 ? ... ? n = k problem(数学)

题意是    ?  1  ?  2  ?  ...  ?  n = k 式子中给k,? 处可以填 + 也可以填 - ,问最小满足条件的n。 e.g k = 12  - 1 + 2 + 3 + 4 + 5 + 6 - 7 = 12 with n = 7。 先给证明,令 S(n) = 1 + 2 + 3 + 4 + 5 + .... + n 暴搜n,搜出当 S(n) >=

uva 11044 Searching for Nessy(小学数学)

题意是给出一个n*m的格子,求出里面有多少个不重合的九宫格。 (rows / 3) * (columns / 3) K.o 代码: #include <stdio.h>int main(){int ncase;scanf("%d", &ncase);while (ncase--){int rows, columns;scanf("%d%d", &rows, &col

数论入门整理(updating)

一、gcd lcm 基础中的基础,一般用来处理计算第一步什么的,分数化简之类。 LL gcd(LL a, LL b) { return b ? gcd(b, a % b) : a; } <pre name="code" class="cpp">LL lcm(LL a, LL b){LL c = gcd(a, b);return a / c * b;} 例题:

【生成模型系列(初级)】嵌入(Embedding)方程——自然语言处理的数学灵魂【通俗理解】

【通俗理解】嵌入(Embedding)方程——自然语言处理的数学灵魂 关键词提炼 #嵌入方程 #自然语言处理 #词向量 #机器学习 #神经网络 #向量空间模型 #Siri #Google翻译 #AlexNet 第一节:嵌入方程的类比与核心概念【尽可能通俗】 嵌入方程可以被看作是自然语言处理中的“翻译机”,它将文本中的单词或短语转换成计算机能够理解的数学形式,即向量。 正如翻译机将一种语言

【Linux 从基础到进阶】Ansible自动化运维工具使用

Ansible自动化运维工具使用 Ansible 是一款开源的自动化运维工具,采用无代理架构(agentless),基于 SSH 连接进行管理,具有简单易用、灵活强大、可扩展性高等特点。它广泛用于服务器管理、应用部署、配置管理等任务。本文将介绍 Ansible 的安装、基本使用方法及一些实际运维场景中的应用,旨在帮助运维人员快速上手并熟练运用 Ansible。 1. Ansible的核心概念

数论ZOJ 2562

题意:给定一个数N,求小于等于N的所有数当中,约数最多的一个数,如果存在多个这样的数,输出其中最大的一个。 分析:反素数定义:对于任何正整数x,其约数的个数记做g(x).例如g(1)=1,g(6)=4.如果某个正整数x满足:对于任意i(0<i<x),都有g(i)<g(x),则称x为反素数。 性质一:一个反素数的质因子必然是从2开始连续的质数。 性质二:p=2^t1*3^t2*5^t3*7

AI基础 L9 Local Search II 局部搜索

Local Beam search 对于当前的所有k个状态,生成它们的所有可能后继状态。 检查生成的后继状态中是否有任何状态是解决方案。 如果所有后继状态都不是解决方案,则从所有后继状态中选择k个最佳状态。 当达到预设的迭代次数或满足某个终止条件时,算法停止。 — Choose k successors randomly, biased towards good ones — Close