面向零基础的 C++ 初等数论教程,包含数论基础概念以及如何用 C++ 实现相关算法。

1. 数论基础概念

1.1 素数

素数是大于 1 且只能被 1 和自身整除的自然数。例如,2、3、5、7 是素数,而 4(能被 2 整除)、6(能被 2 和 3 整除)不是素数。

1.2 最大公约数(GCD)

两个或多个整数共有约数中最大的一个。例如,12 和 18 的公约数有 1、2、3、6,所以它们的最大公约数是 6。

1.3 最小公倍数(LCM)

两个或多个整数公有的倍数中最小的一个。例如,4 和 6 的公倍数有 12、24 等,所以它们的最小公倍数是 12。

2. 用 C++ 实现数论算法

2.1 判断素数

#include <iostream>
bool isPrime(int n) {
    if (n <= 1) return false;
    for (int i = 2; i * i <= n; ++i) {
        if (n % i == 0) return false;
    }
    return true;
}

int main() {
    int num = 7;
    if (isPrime(num)) {
        std::cout << num << " 是素数" << std::endl;
    } else {
        std::cout << num << " 不是素数" << std::endl;
    }
    return 0;
}

代码解释

  • 对于小于等于 1 的数,直接判定不是素数。
  • 从 2 开始到 n\sqrt{n} 进行遍历,如果 n 能被其中任何一个数整除,则 n 不是素数。

2.2 计算最大公约数(欧几里得算法)

#include <iostream>
int gcd(int a, int b) {
    while (b != 0) {
        int temp = b;
        b = a % b;
        a = temp;
    }
    return a;
}

int main() {
    int a = 12, b = 18;
    std::cout << "最大公约数是: " << gcd(a, b) << std::endl;
    return 0;
}

代码解释

  • 欧几里得算法基于原理:gcd(a,b)=gcd(b,amodb)\gcd(a, b) = \gcd(b, a \bmod b),不断更新 ab 的值,直到 b 为 0,此时 a 就是最大公约数。

2.3 计算最小公倍数

#include <iostream>
int gcd(int a, int b) {
    while (b != 0) {
        int temp = b;
        b = a % b;
        a = temp;
    }
    return a;
}

int lcm(int a, int b) {
    return a / gcd(a, b) * b;
}

int main() {
    int a = 4, b = 6;
    std::cout << "最小公倍数是: " << lcm(a, b) << std::endl;
    return 0;
}

代码解释

  • 最小公倍数与最大公约数的关系为:lcm(a,b)=a×bgcd(a,b)\text{lcm}(a, b)=\frac{a\times b}{\gcd(a, b)},先计算最大公约数,再根据公式计算最小公倍数。

3. 更高级的数论算法:素数筛法

3.1 埃氏筛法

#include <iostream>
#include <vector>
std::vector<int> sieveOfEratosthenes(int n) {
    std::vector<bool> isPrime(n + 1, true);
    isPrime[0] = isPrime[1] = false;
    for (int i = 2; i * i <= n; ++i) {
        if (isPrime[i]) {
            for (int j = i * i; j <= n; j += i) {
                isPrime[j] = false;
            }
        }
    }
    std::vector<int> primes;
    for (int i = 2; i <= n; ++i) {
        if (isPrime[i]) {
            primes.push_back(i);
        }
    }
    return primes;
}

int main() {
    int n = 100;
    std::vector<int> primes = sieveOfEratosthenes(n);
    std::cout << "1 到 " << n << " 之间的素数有: ";
    for (int prime : primes) {
        std::cout << prime << " ";
    }
    std::cout << std::endl;
    return 0;
}

代码解释

  • 从 2 开始,将每个素数的倍数标记为合数,直到遍历完所有小于等于 n\sqrt{n} 的数。
  • 最后收集所有未被标记的数,即为素数。

3.2 线性筛法

#include <iostream>
#include <vector>
std::vector<int> sieveOfEuler(int n) {
    std::vector<bool> isPrime(n + 1, true);
    std::vector<int> primes;
    for (int i = 2; i <= n; ++i) {
        if (isPrime[i]) {
            primes.push_back(i);
        }
        for (int j = 0; j < primes.size() && i * primes[j] <= n; ++j) {
            isPrime[i * primes[j]] = false;
            if (i % primes[j] == 0) {
                break;
            }
        }
    }
    return primes;
}

int main() {
    int n = 100;
    std::vector<int> primes = sieveOfEuler(n);
    std::cout << "1 到 " << n << " 之间的素数有: ";
    for (int prime : primes) {
        std::cout << prime << " ";
    }
    std::cout << std::endl;
    return 0;
}

代码解释

  • 线性筛法保证每个合数只被它的最小质因子筛去,避免了埃氏筛法的重复标记问题,时间复杂度为 O(n)O(n)

4. 练习建议

  • 尝试修改上述代码,使其能处理更大范围的数。
  • 编写程序,找出给定范围内的所有孪生素数(相差为 2 的素数对)。
  • 实现扩展欧几里得算法,用于求解线性同余方程。

通过以上内容,你可以对 C++ 实现初等数论算法有一个基础的了解,后续可以通过更多的练习和学习来深入掌握。

8 条评论

  • @ 2025-5-3 12:21:26

    数学幂函数零基础教程

    一、幂函数的基本概念

    1. 什么是幂函数

    幂函数是形如 y=xay = x^aaa 为常数)的函数,其中 xx 是自变量,yy 是因变量。这里的 xx 是底数,aa 是指数。比如 y=x2y = x^2y=x3y = x^3y=x12y = x^{\frac{1}{2}} 等都是幂函数。

    2. 幂函数与乘方运算的关系

    乘方运算是幂函数的基础。对于一个数 xx 和正整数 nnxnx^n 表示 nnxx 相乘。例如:

    • 232^3 表示 3 个 2 相乘,即 23=2×2×2=82^3=2×2×2 = 8
    • (3)2(-3)^2 表示 2 个 -3 相乘,(3)2=(3)×(3)=9(-3)^2=(-3)×(-3)=9

    3. 指数的取值范围及特殊情况

    • 正整数指数:当 aa 是正整数时,xax^a 就是普通的乘方运算。如 y=x5y = x^5xx 可以取任意实数。
    • 零指数:规定 x0=1x^0 = 1x0x\neq0)。因为当 x0x\neq0 时,xn÷xn=xnn=x0x^n\div x^n=x^{n - n}=x^0,而 xn÷xn=1x^n\div x^n = 1。例如 50=15^0 = 1(2)0=1(-2)^0 = 1
    • 负整数指数:当 aa 是负整数时,设 a=na=-nnn 是正整数),则 xa=1xnx^a=\frac{1}{x^n}x0x\neq0)。比如 x2=1x2x^{-2}=\frac{1}{x^2}x0x\neq0),当 x=3x = 3 时,32=132=193^{-2}=\frac{1}{3^2}=\frac{1}{9}
    • 分数指数:当 a=mna=\frac{m}{n}mmnn 是整数,n>0n\gt0)时,xmn=xmnx^{\frac{m}{n}}=\sqrt[n]{x^m}x0x\geq0nn 为偶数时)。例如 x12=xx^{\frac{1}{2}}=\sqrt{x}x0x\geq0),x23=x23x^{\frac{2}{3}}=\sqrt[3]{x^2}xx 可以取任意实数。

    二、幂函数的图像与性质

    1. 不同指数下幂函数的图像绘制

    • y=x2y = x^2

      • 图像特点:它的图像是一个开口向上的抛物线,对称轴是 yy 轴(x=0x = 0),顶点坐标是 (0,0)(0,0)。当 x<0x\lt0 时,函数值 yyxx 的增大而减小;当 x>0x\gt0 时,函数值 yyxx 的增大而增大。
    • y=x3y = x^3

      • 图像特点:它的图像关于原点对称,是奇函数。函数在 RR 上单调递增,即随着 xx 的增大,yy 也一直增大。
    • y=x12=xy = x^{\frac{1}{2}}=\sqrt{x}

      • 图像特点:定义域为 x0x\geq0,图像在第一象限,从左到右呈上升趋势,函数单调递增。

    2. 幂函数的性质总结

    • 定义域
      • aa 是正整数时,定义域是 RR
      • a=0a = 0 时,定义域是 x0x\neq0
      • aa 是负整数时,定义域是 x0x\neq0
      • a=mna=\frac{m}{n}mmnn 互质):
        • nn 是奇数,定义域是 RR;若 nn 是偶数,定义域是 x0x\geq0
    • 值域
      • 不同的幂函数值域不同。例如 y=x2y = x^2 的值域是 y0y\geq0y=x3y = x^3 的值域是 RRy=x12y = x^{\frac{1}{2}} 的值域是 y0y\geq0
    • 奇偶性
      • f(x)=f(x)f(-x)=f(x),则函数是偶函数,图像关于 yy 轴对称,如 y=x2y = x^2
      • f(x)=f(x)f(-x)=-f(x),则函数是奇函数,图像关于原点对称,如 y=x3y = x^3
      • 有些幂函数既不是奇函数也不是偶函数,如 y=x12y = x^{\frac{1}{2}},因为其定义域不关于原点对称。
    • 单调性
      • a>0a\gt0 时,幂函数在 (0,+)(0,+\infty) 上单调递增。
      • a<0a\lt0 时,幂函数在 (0,+)(0,+\infty) 上单调递减。

    三、幂函数的应用实例

    1. 面积与边长的关系

    正方形的面积 SS 与边长 xx 的关系是 S=x2S = x^2,这就是一个幂函数。如果已知正方形的边长 x=5x = 5 厘米,那么根据幂函数可以计算出面积 S=52=25S = 5^2=25 平方厘米。

    2. 体积与棱长的关系

    正方体的体积 VV 与棱长 xx 的关系是 V=x3V = x^3。若正方体的棱长 x=3x = 3 分米,那么体积 V=33=27V = 3^3 = 27 立方分米。

    3. 实际问题中的增长与衰减

    在某些实际问题中,幂函数可以用来描述增长或衰减的情况。例如,某种生物的数量 NN 与时间 tt 的关系可以近似表示为 N=N0taN = N_0t^aN0N_0 是初始数量)。当 a>1a\gt1 时,生物数量呈增长趋势;当 0<a<10\lt a\lt1 时,增长速度会逐渐变慢。

    四、幂函数的运算

    1. 同底数幂的乘法

    同底数幂相乘,底数不变,指数相加。即 xm×xn=xm+nx^m\times x^n=x^{m + n}mmnn 为实数)。例如 23×22=23+2=25=322^3\times2^2=2^{3 + 2}=2^5 = 32

    2. 同底数幂的除法

    同底数幂相除,底数不变,指数相减。即 xm÷xn=xmnx^m\div x^n=x^{m - n}x0x\neq0mmnn 为实数)。例如 54÷52=542=52=255^4\div5^2=5^{4 - 2}=5^2 = 25

    3. 幂的乘方

    幂的乘方,底数不变,指数相乘。即 (xm)n=xmn(x^m)^n=x^{mn}mmnn 为实数)。例如 (32)3=32×3=36=729(3^2)^3=3^{2×3}=3^6 = 729

    4. 积的乘方

    积的乘方,等于把积的每一个因式分别乘方,再把所得的幂相乘。即 (xy)n=xnyn(xy)^n=x^n y^nnn 为实数)。例如 (2×3)2=22×32=4×9=36(2\times3)^2=2^2\times3^2 = 4\times9 = 36

    五、练习题

    1. 计算

    • 计算 343^4(2)5(-2)^5(12)3(\frac{1}{2})^{-3}
    • 化简 x3×x5x^3\times x^5(x2)4(x^2)^4(2x)3(2x)^3

    2. 判断奇偶性

    判断函数 y=x4y = x^4y=x5y = x^5y=x13y = x^{\frac{1}{3}} 的奇偶性。

    3. 实际应用

    已知一个正方体的体积是 64 立方米,求它的棱长。

    练习题答案

    1. 计算

    • 34=3×3×3×3=813^4=3×3×3×3 = 81(2)5=(2)×(2)×(2)×(2)×(2)=32(-2)^5=(-2)×(-2)×(-2)×(-2)×(-2)= - 32;$(\frac{1}{2})^{-3}=\frac{1}{(\frac{1}{2})^3}=\frac{1}{\frac{1}{8}} = 8$。
    • x3×x5=x3+5=x8x^3\times x^5=x^{3 + 5}=x^8(x2)4=x2×4=x8(x^2)^4=x^{2×4}=x^8(2x)3=23×x3=8x3(2x)^3=2^3\times x^3 = 8x^3

    2. 判断奇偶性

    • 对于 y=x4y = x^4f(x)=(x)4=x4=f(x)f(-x)=(-x)^4=x^4=f(x),所以 y=x4y = x^4 是偶函数。
    • 对于 y=x5y = x^5f(x)=(x)5=x5=f(x)f(-x)=(-x)^5=-x^5=-f(x),所以 y=x5y = x^5 是奇函数。
    • 对于 y=x13y = x^{\frac{1}{3}}f(x)=(x)13=x13=f(x)f(-x)=(-x)^{\frac{1}{3}}=-x^{\frac{1}{3}}=-f(x),所以 y=x13y = x^{\frac{1}{3}} 是奇函数。

    3. 实际应用

    设正方体的棱长为 xx 米,由 V=x3V = x^3,已知 V=64V = 64,则 x3=64x^3 = 64,解得 x=4x = 4 米。

    通过以上内容,你应该对幂函数有了一个较为全面的认识。从基本概念到图像性质,再到实际应用和运算,逐步深入学习幂函数,通过不断练习来巩固所学知识。

    • @ 2025-5-3 12:20:10

      📘 数学幂函数教程(从零开始,详细讲解)

      📌 什么是幂函数?

      幂函数 是数学中最基本、最常用的一种函数之一。它的形式通常为:

      f(x)=axf(x) = a^x

      其中:

      • a a 底数(base),必须是正实数;
      • x x 指数(exponent),可以是整数、分数、负数甚至无理数。

      ✅ 学习目标

      • 理解什么是幂函数及其基本性质;
      • 掌握幂函数的图像与变化规律;
      • 理解并能应用幂的运算法则;
      • 能解决简单的幂函数相关问题;
      • 适合数学零基础或初中/高中学生学习。

      🧠 一、什么是“幂”?

      1. 定义:

      “幂” 就是 一个数自乘若干次 的结果。

      例如:

      • 23=2×2×2=8 2^3 = 2 \times 2 \times 2 = 8
      • 52=5×5=25 5^2 = 5 \times 5 = 25

      这里的数字 2 和 5 叫做 底数,3 和 2 叫做 指数


      🔢 二、幂的基本运算规则(重点!)

      掌握以下这些公式非常重要!

      运算 公式 示例
      相同底数相乘 aman=am+n a^m \cdot a^n = a^{m+n} 2324=27=128 2^3 \cdot 2^4 = 2^{7} = 128
      相同底数相除 aman=amn \frac{a^m}{a^n} = a^{m-n} 3532=33=27 \frac{3^5}{3^2} = 3^{3} = 27
      幂的幂 (am)n=amn (a^m)^n = a^{m \cdot n} (23)2=26=64 (2^3)^2 = 2^{6} = 64
      幂相乘(不同底) ambm=(ab)m a^m \cdot b^m = (ab)^m 2333=(23)3=63=216 2^3 \cdot 3^3 = (2\cdot3)^3 = 6^3 = 216
      负指数 an=1an a^{-n} = \frac{1}{a^n} 23=123=18 2^{-3} = \frac{1}{2^3} = \frac{1}{8}
      零指数 a0=1 a^0 = 1 a0 a \ne 0 50=1 5^0 = 1

      ⚠️ 注意:任何非零数的 0 次方都是 1,但 0 的 0 次方是没有定义的。


      📈 三、幂函数的图像

      我们来看几个常见的幂函数图像:

      1. f(x)=2x f(x) = 2^x

      这是最常见的指数函数,底数大于 1,图像如下:

            |
           *|
          * |
         *  |
        *   |
       *____|_________
            0
      
      • x>0 x > 0 ,值越来越大(增长很快)
      • x<0 x < 0 ,值越来越小,趋近于 0
      • 始终在 x 轴上方(值永远为正)

      2. f(x)=(12)x f(x) = \left(\frac{1}{2}\right)^x

      底数小于 1,图像如下:

      *______|
       *     |
        *    |
         *   |
          *  |
           * |
            *|
             |________
            -3 -2 -1 0 1 2 3
      
      • x>0 x > 0 ,值越来越小,趋近于 0
      • x<0 x < 0 ,值越来越大

      📊 四、常见幂函数类型

      类型 函数形式 特点
      正整数指数函数 f(x)=ax f(x) = a^x , a>1 a > 1 快速上升
      分数指数函数 f(x)=a1/n f(x) = a^{1/n} 表示开根号,如 a1/2=a a^{1/2} = \sqrt{a}
      负指数函数 f(x)=ax f(x) = a^{-x} 图像是递减的
      零指数函数 f(x)=a0=1 f(x) = a^0 = 1 恒等于 1
      指数为变量 f(x)=xn f(x) = x^n 称为幂函数,如 x2 x^2 x3 x^3

      📝 五、幂函数的实际应用

      应用领域 使用场景
      计算利息 复利计算:A=P(1+r)t A = P(1 + r)^t
      生物学 细菌繁殖模型:数量按指数增长
      物理学 放射性衰变:N(t)=N0ekt N(t) = N_0 e^{-kt}
      计算机科学 算法复杂度分析:如 O(n2) O(n^2) O(2n) O(2^n)
      经济学 GDP增长模型、人口增长等

      📖 六、例题解析(带步骤)

      ❓ 例1:计算 34 3^4

      ✅ 解答:

      34=3×3×3×3=813^4 = 3 \times 3 \times 3 \times 3 = 81

      ❓ 例2:化简 2325 2^3 \cdot 2^5

      ✅ 解答:

      2325=23+5=28=2562^3 \cdot 2^5 = 2^{3+5} = 2^8 = 256

      ❓ 例3:化简 5754 \frac{5^7}{5^4}

      ✅ 解答:

      5754=574=53=125\frac{5^7}{5^4} = 5^{7-4} = 5^3 = 125

      ❓ 例4:化简 (42)3 (4^2)^3

      ✅ 解答:

      (42)3=423=46=4096(4^2)^3 = 4^{2 \cdot 3} = 4^6 = 4096

      ❓ 例5:计算 32 3^{-2}

      ✅ 解答:

      32=132=193^{-2} = \frac{1}{3^2} = \frac{1}{9}

      📚 七、进阶概念(可选)

      1. 分数指数(根号表示)

      • a1/2=a a^{1/2} = \sqrt{a}
      • a1/3=a3 a^{1/3} = \sqrt[3]{a}
      • am/n=amn a^{m/n} = \sqrt[n]{a^m}

      例如:

      • 161/2=16=4 16^{1/2} = \sqrt{16} = 4
      • 272/3=(273)2=32=9 27^{2/3} = (\sqrt[3]{27})^2 = 3^2 = 9

      2. 自然指数函数 ex e^x

      • e2.71828... e \approx 2.71828... 是一个重要的常数
      • 形式为 f(x)=ex f(x) = e^x
      • 在微积分和自然现象中非常常见

      📝 总结

      内容 关键点
      幂的定义 一个数自乘若干次
      幂的运算法则 加法、减法、乘法、幂的幂、负指数等
      图像特点 底数大于1时快速增长,小于1时递减
      实际应用 利息、物理、生物、计算机等
      扩展知识 根号、自然指数 ex e^x

      📚 练习题(建议动手做一遍)

      1. 计算:43 4^3
      2. 化简:2522 2^5 \cdot 2^2
      3. 化简:7975 \frac{7^9}{7^5}
      4. 化简:(53)2 (5^3)^2
      5. 计算:24 2^{-4}
      6. 化简:82/3 8^{2/3}
      • @ 2025-5-3 12:04:05

        快速幂是一种高效计算幂次的算法,它可以将计算 ana^n 的时间复杂度从朴素算法的 O(n)O(n) 降低到 O(logn)O(log n)。下面为你详细介绍快速幂算法的原理和实现,以及如何在 C++ 中实现它。

        原理

        快速幂算法的核心思想是利用幂次的二进制分解。假设我们要计算 ana^n,可以将 nn 表示为二进制形式,例如:n=21k+22k++2mkn = 2^k_1+2^k_2+\cdots+2^k_m。那么 ana^n 就可以写成 $a^{2^k_1}\times a^{2^k_2}\times\cdots\times a^{2^k_m}$。

        例如,计算 a13a^{13},因为 1313 的二进制表示是 11011101,即 13=23+22+2013 = 2^3 + 2^2 + 2^0,所以 a13=a23×a22×a20a^{13}=a^{2^3}\times a^{2^2}\times a^{2^0}

        代码实现

        以下是使用 C++ 实现快速幂的代码:

        #include <iostream>
        
        // 快速幂函数
        long long fastPower(long long a, long long n) {
            long long result = 1;
            while (n > 0) {
                if (n & 1) {  // 判断 n 的二进制最后一位是否为 1
                    result *= a;
                }
                a *= a;  // a 平方
                n >>= 1;  // n 右移一位,相当于除以 2
            }
            return result;
        }
        
        int main() {
            long long a = 2;
            long long n = 13;
            long long ans = fastPower(a, n);
            std::cout << a << " 的 " << n << " 次幂是: " << ans << std::endl;
            return 0;
        }
        

        代码解释

        1. 初始化结果result 初始化为 1,用于存储最终结果。
        2. 循环条件:当 n > 0 时,继续循环。
        3. 判断二进制最后一位:使用 n & 1 判断 n 的二进制最后一位是否为 1,如果是 1,则将当前的 a 乘到 result 中。
        4. 平方操作:将 a 平方,即 a *= a
        5. 右移操作:将 n 右移一位,相当于将 n 除以 2。
        6. 返回结果:当 n 变为 0 时,循环结束,返回 result

        复杂度分析

        • 时间复杂度O(logn)O(log n),因为每次循环 n 都会减半。
        • 空间复杂度O(1)O(1),只使用了常数级的额外空间。

        取模运算

        在实际应用中,幂次的结果可能会非常大,为了避免溢出,通常会对结果取模。以下是带有取模运算的快速幂代码:

        #include <iostream>
        
        const long long MOD = 1e9 + 7;
        
        // 带取模的快速幂函数
        long long fastPowerMod(long long a, long long n) {
            long long result = 1;
            a %= MOD;  // 防止 a 过大
            while (n > 0) {
                if (n & 1) {
                    result = (result * a) % MOD;
                }
                a = (a * a) % MOD;
                n >>= 1;
            }
            return result;
        }
        
        int main() {
            long long a = 2;
            long long n = 13;
            long long ans = fastPowerMod(a, n);
            std::cout << a << " 的 " << n << " 次幂对 " << MOD << " 取模的结果是: " << ans << std::endl;
            return 0;
        }
        

        这个代码在每次乘法操作后都对结果取模,确保结果不会溢出。

        • @ 2025-5-3 11:35:45

          通过枚举法求最小公倍数

          #include<iostream>
          using namespace std;
          int main() {
          	int a,b;
          	scanf("%d %d",&a,&b);//a < b
          	if(a > b){
          		swap(a,b);
          	}
          	for(int i=1;;i++){
          		if(i*a % b == 0){
          			printf("%d",i*a);
          			break;
          		}
          	}
          	
          	return 0;
          }
          
          • @ 2025-5-1 15:36:03

            C++ 初等数论教程 —— 0基础详细讲解

            📘 前言:什么是初等数论?

            初等数论(Elementary Number Theory)是研究整数的基本性质的数学分支。它不涉及复杂的数学工具如实分析或复分析,而是主要研究整数的除法、最大公约数、最小公倍数、素数、模运算等内容。

            在编程中,尤其是算法设计、密码学、竞赛编程等领域,初等数论是非常重要的基础知识。


            🧮 第一章:基本概念与符号

            1.1 整数与自然数

            • 整数集合:... -3, -2, -1, 0, 1, 2, 3 ...
            • 自然数集合:0 或者 1 开始(不同定义),通常我们用 unsigned int 表示自然数范围的正整数。

            1.2 取模运算(Modulo)

            取模运算是一个非常关键的操作。

            • 记作:a % b,表示 a 除以 b 的余数。
            • 规则:
              • 如果 a < 0,则结果也为负(C++ 中行为需注意)。
              • 例如:7 % 5 = 2;(-7) % 5 = -2(不是最简形式的模运算结果)。
            #include <iostream>
            using namespace std;
            
            int main() {
                cout << "7 % 5 = " << 7 % 5 << endl;     // 输出 2
                cout << "-7 % 5 = " << -7 % 5 << endl;   // 输出 -2
            }
            

            ✅ 注意:在 C++ 中,模运算的结果符号和第一个操作数相同。


            🔢 第二章:整除性与最大公约数

            2.1 整除(Divisibility)

            如果整数 a 能被整数 b 整除,记作:b | a,即存在整数 k,使得 a = b × k。

            例如:3 | 6,因为 6 = 3 × 2;但 3 ∤ 7。

            判断方式:

            if (a % b == 0) {
                cout << b << " 整除 " << a << endl;
            }
            

            2.2 最大公约数 GCD(Greatest Common Divisor)

            两个整数的最大公约数是指能同时整除这两个数的最大正整数。

            欧几里得算法(辗转相除法)

            这是求最大公约数的经典方法,基于以下定理:

            gcd(a, b) = gcd(b, a % b)

            递归实现:

            int gcd(int a, int b) {
                if (b == 0)
                    return a;
                return gcd(b, a % b);
            }
            

            测试代码:

            #include <iostream>
            using namespace std;
            
            int gcd(int a, int b) {
                if (b == 0)
                    return a;
                return gcd(b, a % b);
            }
            
            int main() {
                int a = 48, b = 18;
                cout << "gcd(" << a << ", " << b << ") = " << gcd(a, b) << endl;
                return 0;
            }
            

            输出:

            gcd(48, 18) = 6
            

            📐 第三章:最小公倍数 LCM(Least Common Multiple)

            最小公倍数是两个整数能同时被整除的最小正整数。

            公式:

            lcm(a, b) = a * b / gcd(a, b)

            ⚠️ 注意:为了避免溢出,建议使用 long long 类型。

            long long lcm(int a, int b) {
                return (long long)a * b / gcd(a, b);  // 需要先定义前面的 gcd 函数
            }
            

            🧩 第四章:素数(质数)

            4.1 定义

            素数(Prime Number)是指大于1且只能被1和自身整除的整数。

            例如:2, 3, 5, 7, 11...

            4.2 素数判断函数

            我们可以写一个简单函数来判断一个数是否为素数。

            bool isPrime(int n) {
                if (n <= 1) return false;
                if (n == 2) return true;
                if (n % 2 == 0) return false;
                
                for (int i = 3; i*i <= n; i += 2) {
                    if (n % i == 0)
                        return false;
                }
                return true;
            }
            

            测试:

            cout << "Is 17 prime? " << isPrime(17) << endl;  // 输出 1(true)
            cout << "Is 20 prime? " << isPrime(20) << endl;  // 输出 0(false)
            

            4.3 枚举小于等于 n 的所有素数(埃拉托色尼筛法 Sieve of Eratosthenes)

            这是一个经典的生成所有素数的方法。

            #include <iostream>
            #include <vector>
            using namespace std;
            
            void sieve(int n) {
                vector<bool> is_prime(n+1, true);
                is_prime[0] = is_prime[1] = false;
            
                for (int i = 2; i*i <= n; ++i) {
                    if (is_prime[i]) {
                        for (int j = i*i; j <= n; j += i) {
                            is_prime[j] = false;
                        }
                    }
                }
            
                cout << "小于等于 " << n << " 的素数有:\n";
                for (int i = 2; i <= n; ++i) {
                    if (is_prime[i])
                        cout << i << " ";
                }
                cout << endl;
            }
            

            调用:

            sieve(30);
            

            输出:

            小于等于 30 的素数有:
            2 3 5 7 11 13 17 19 23 29
            

            🧮 第五章:同余与模运算进阶

            5.1 同余关系(Congruence)

            如果两个整数 a 和 b 在除以 m 后余数相同,那么称它们对 m 同余,记作:

            a ≡ b (mod m)

            等价于:m | (a - b)

            例如:10 ≡ 3 (mod 7),因为 10 - 3 = 7,能被 7 整除。


            5.2 模运算的性质

            • (a + b) % m = ((a % m) + (b % m)) % m
            • (a - b) % m = ((a % m) - (b % m) + m) % m
            • (a × b) % m = ((a % m) × (b % m)) % m

            这些性质在处理大数时非常重要。


            5.3 快速幂(Exponentiation Modulo)

            快速计算 abmodm a^b \mod m

            long long mod_pow(long long a, long long b, long long m) {
                long long result = 1;
                a %= m;
                while (b > 0) {
                    if (b % 2 == 1)
                        result = (result * a) % m;
                    a = (a * a) % m;
                    b /= 2;
                }
                return result;
            }
            

            测试:

            cout << "3^5 mod 7 = " << mod_pow(3, 5, 7) << endl;  // 结果是 5
            

            📋 总结:常用的数论函数一览表

            功能 函数名 时间复杂度
            判断素数 isPrime(n) O(√n)
            最大公约数 gcd(a, b) O(log min(a,b))
            最小公倍数 lcm(a, b)
            筛法求素数 sieve(n) O(n log log n)
            快速幂模运算 mod_pow(a,b,m) O(log b)

            💡 编程练习建议

            1. 编写程序输入一个数 n,输出其所有因数。
            2. 输入两个整数,输出它们的最大公约数和最小公倍数。
            3. 编写程序判断并输出某个范围内所有的素数。
            4. 实现一个加密/解密小程序,用模幂来做简单的 RSA 加密模拟。
            5. 写一个函数判断一个数是不是回文素数(既是回文数又是素数)。

            📚 下一步推荐学习内容

            ✅ 扩展欧几里得算法(用于求 ax + by = gcd(a,b) 的解)
            ✅ 同余方程与逆元(Modular Inverse)
            ✅ 中国剩余定理(CRT)
            ✅ 数论函数(如 φ(n) 欧拉函数)
            ✅ BSGS 算法(大步小步算法)解决离散对数问题


            📌 提示:学习过程中可以结合 LeetCode、洛谷、Codeforces 平台上的题目进行练习,比如:

            • LeetCode 204. 计数质数
            • LeetCode 365. 水壶问题(贝祖定理)
            • Codeforces 上的数论分类题库

            如果你希望继续深入某一部分(如扩展欧几里得、欧拉函数、模线性方程等),欢迎继续提问!

            • @ 2025-5-1 15:17:43

              初等数论是数学的一个分支,专注于整数的性质及其相互关系。对于完全没有基础的学习者来说,可以从以下几个基本概念和主题开始学习:

              1. 基础概念

              • 整数:理解什么是整数(正整数、负整数和零)。
              • 除法与余数:了解如何进行整数除法以及什么是余数。引入模运算的概念,即 a mod b 表示 a 除以 b 的余数。

              2. 质数与合数

              • 质数:只能被 1 和自身整除的大于1的自然数。
              • 合数:除了 1 和它本身之外还能被其他数整除的自然数。
              • 质因数分解:每个合数都可以写成几个质数的乘积的形式,这种表示方法称为质因数分解。

              3. 最大公约数 (GCD) 与最小公倍数 (LCM)

              • 最大公约数 (GCD):两个或多个整数共有约数中最大的一个。
              • 最小公倍数 (LCM):两个或多个整数共有的倍数中最小的一个。GCD 和 LCM 之间存在一定的关系,即两个数的乘积等于它们的最大公约数和最小公倍数的乘积。

              4. 模运算

              • 同余:如果两个数 a 和 b 除以 m 的余数相同,则称 a 和 b 关于模 m 同余,记作 a ≡ b (mod m)

              5. 进一步探索

              • 欧拉定理与费马小定理:这些定理涉及到了同余的一些重要性质。
              • 线性同余方程:形式为 ax ≡ b (mod m) 的方程。
              • 中国剩余定理:解决一系列线性同余方程的方法。
              • @ 2025-5-1 15:17:23

                基础准备

                • 了解C++语言基础,包括变量、数据类型、控制结构(如if - else、循环)、函数等。

                初等数论知识与C++实现

                1. 整除与余数
                  • 学习整除的概念,即一个整数能够被另一个整数整除的关系。
                  • 在C++中,可以使用取模运算符%来计算余数。例如,a % b表示a除以b的余数。当a % b == 0时,说明a能被b整除。
                  • 示例代码:
                #include <iostream>
                
                int main() {
                    int a = 10, b = 3;
                    if (a % b == 0) {
                        std::cout << a << " 能被 " << b << " 整除。" << std::endl;
                    } else {
                        std::cout << a << " 除以 " << b << " 的余数是 " << a % b << std::endl;
                    }
                    return 0;
                }
                
                1. 最大公因数与最小公倍数
                  • 介绍辗转相除法求最大公因数的原理:两个整数的最大公因数等于其中较小的数和两数相除余数的最大公因数。
                  • 用C++实现辗转相除法:
                #include <iostream>
                
                int gcd(int a, int b) {
                    while (b!= 0) {
                        int temp = b;
                        b = a % b;
                        a = temp;
                    }
                    return a;
                }
                
                int main() {
                    int num1 = 24, num2 = 36;
                    int gcdResult = gcd(num1, num2);
                    std::cout << "最大公因数是: " << gcdResult << std::endl;
                    // 最小公倍数 = 两数之积 / 最大公因数
                    int lcmResult = (num1 * num2) / gcdResult;
                    std::cout << "最小公倍数是: " << lcmResult << std::endl;
                    return 0;
                }
                
                1. 质数与合数
                  • 定义质数为大于1且除了1和自身外不能被其他正整数整除的数,合数是除了质数以外的数。
                  • 编写C++函数判断一个数是否为质数:
                #include <iostream>
                #include <cmath>
                
                bool isPrime(int num) {
                    if (num < 2) {
                        return false;
                    }
                    for (int i = 2; i <= std::sqrt(num); i++) {
                        if (num % i == 0) {
                            return false;
                        }
                    }
                    return true;
                }
                
                int main() {
                    int number = 17;
                    if (isPrime(number)) {
                        std::cout << number << " 是质数。" << std::endl;
                    } else {
                        std::cout << number << " 是合数。" << std::endl;
                    }
                    return 0;
                }
                
                1. 素数筛法
                  • 讲解埃拉托斯特尼筛法,用于找出一定范围内的所有质数。其原理是从2开始,将每个质数的倍数都标记为合数,剩下的就是质数。
                  • 用C++实现埃拉托斯特尼筛法:
                #include <iostream>
                #include <vector>
                
                void sieveOfEratosthenes(int n) {
                    std::vector<bool> isPrime(n + 1, true);
                    isPrime[0] = isPrime[1] = false;
                
                    for (int p = 2; p * p <= n; p++) {
                        if (isPrime[p]) {
                            for (int i = p * p; i <= n; i += p) {
                                isPrime[i] = false;
                            }
                        }
                    }
                
                    for (int i = 2; i <= n; i++) {
                        if (isPrime[i]) {
                            std::cout << i << " ";
                        }
                    }
                }
                
                int main() {
                    int n = 30;
                    std::cout << "小于等于 " << n << " 的质数有: ";
                    sieveOfEratosthenes(n);
                    return 0;
                }
                
                1. 同余
                  • 介绍同余的概念:如果两个整数ab除以同一个正整数m所得的余数相同,则称ab对于模m同余,记作a ≡ b (mod m)
                  • 实现判断两个数是否同余的C++函数:
                #include <iostream>
                
                bool isCongruent(int a, int b, int m) {
                    return (a % m == b % m);
                }
                
                int main() {
                    int num1 = 17, num2 = 29, mod = 6;
                    if (isCongruent(num1, num2, mod)) {
                        std::cout << num1 << " 和 " << num2 << " 对于模 " << mod << " 同余。" << std::endl;
                    } else {
                        std::cout << num1 << " 和 " << num2 << " 对于模 " << mod << " 不同余。" << std::endl;
                    }
                    return 0;
                }
                

                练习与实践

                • 完成一些基础的数论相关的编程练习题,如判断一个数是否为完全数、求一个数的所有因数等。
                • 尝试解决一些简单的实际问题,例如在密码学中,利用初等数论的知识进行简单的加密和解密操作。

                进阶学习

                • 学习更深入的数论算法,如中国剩余定理、费马小定理等,并使用C++实现。
                • 了解数论在计算机科学中的更多应用,如哈希函数、随机数生成等。

                在学习过程中,要多思考、多实践,遇到问题及时查阅资料或向他人请教。同时,可以参考一些专业的数论书籍,如《初等数论》(第三版,潘承洞、潘承彪著),加深对初等数论知识的理解。

                • @ 2025-5-1 15:13:45

                  C++ 编程语言本身并不直接提供数论的教程,但是我们可以讨论如何使用 C++ 来实现初等数论中的一些基本概念和算法。对于 0 基础的学习者来说,首先需要了解一些基础的编程概念,如变量、循环、条件语句等,之后可以开始学习如何用 C++ 实现数论中的概念。

                  以下是一个简单的路径来学习 C++ 中的初等数论:

                  1. 学习 C++ 基础

                  • 数据类型:了解整型(int)、浮点型(float, double)等基本数据类型。
                  • 控制结构:包括 if-else 条件判断、for 循环、while 循环等。
                  • 函数:学习如何定义和调用函数。
                  • 数组与向量:掌握数组的基本操作以及标准模板库(STL)中的 vector 类。

                  2. 初等数论基础

                  在具备了基础的 C++ 知识后,可以开始学习数论的基础知识,比如:

                  • 质数:理解什么是质数,如何检测一个数是否为质数。
                  • 最大公约数(GCD):学习欧几里得算法来计算两个数的最大公约数。
                  • 最小公倍数(LCM):利用 GCD 计算 LCM。
                  • 模运算:了解取模运算的概念及其应用。

                  3. 使用 C++ 实现数论算法

                  • 质数检测:编写函数来判断一个给定的数字是否是质数。
                  • GCD 和 LCM:使用 C++ 实现欧几里得算法来找到两个数的最大公约数,并进一步计算它们的最小公倍数。
                  • 素因数分解:编写程序将一个整数分解为其素因数的乘积。

                  4. 进一步探索

                  随着你对 C++ 和初等数论的理解加深,你可以尝试更复杂的算法和问题,如:

                  • 大数运算
                  • 模幂运算
                  • 数论变换
                  • 1