信息学竞赛算法——初等数论01

教学目录

  1. 数论基础概念
  2. 数的分类系统
  3. 整除理论与取整运算
  4. 因数与倍数体系
  5. 奇偶性理论
  6. 最大公约数算法
  7. 最小公倍数算法
  8. 数系对比

1. 数论基础概念

1.1 数论定义

研究整数性质的数学分支,核心关注:

  • 数的结构特性
  • 代数关系
  • 方程整数解
  • 素数分布规律

1.2 数论应用

  • 密码学(RSA算法)
  • 计算机校验码
  • 算法优化
  • 组合数学

2. 数的分类系统

数系包含关系

复数 (ℂ)
├── 实数 (ℝ)
│   ├── 有理数 (ℚ)
│   │   ├── 整数 (ℤ)
│   │   │   ├── 自然数 (ℕ)
│   │   │   └── 负整数
│   │   └── 分数(如1/2)
│   └── 无理数(如√2, π)
└── 虚数 (𝕀)
    └── 纯虚数(如5i)

2.1 自然数(ℕ)

定义:非负整数集合 {0,1,2,3,…}

C++特性

unsigned int natural = 10;  // 无符号整型
size_t count = 100;         // 标准库容器使用

2.2 整数(ℤ)

定义:包含正整数、零、负整数

C++实现

int positive = +15;    // 显式正号
int negative = -0x1A;  // 十六进制负数
int zero = 0;          // 零值

2.3 有理数(ℚ)

数学定义:可表示为a/b的数(b≠0)

C++结构体

struct Rational {
    long numerator;
    long denominator;
    
    void simplify() {  // 约分函数
        int g = gcd(abs(numerator), abs(denominator));
        numerator /= g;
        denominator /= g;
        if(denominator < 0) {  // 保证分母正数
            numerator = -numerator;
            denominator = -denominator;
        }
    }
};

2.4 无理数

特征

  • 无限不循环小数
  • 不能表示为分数
  • 常见例子:√2, π, e

C++处理

#include <cmath>

double sqrt3 = sqrt(3);    // 1.73205...
double pi = acos(-1.0);    // 3.14159...
double golden_ratio = (1 + sqrt(5))/2; // 黄金分割率

2.5 实数(ℝ)

组成:有理数与无理数的并集

计算机表示

float  fp32 = 3.14159f;   // 32位浮点
double fp64 = 2.71828;    // 64位浮点

2.6 虚数(𝕀)

数学定义:形如bi的数(b∈ℝ且b≠0,i²=-1)

C++表示

#include <complex>
using namespace std::complex_literals;

auto pureImaginary = 5i;  // 纯虚数类型:complex<double>

2.7 复数(ℂ)

标准形式:z = a + bi(a,b∈ℝ)

C++实现

std::complex<double> z1(3, 4);   // 3+4i
std::complex<double> z2 = 2.5 + 3i; 

// 基本操作
auto sum = z1 + z2;       // (5.5+7i)
auto product = z1 * z2;   // (7.5+17i)

3. 整除理论与取整运算

3.1 整除判定

数学定义:a能被b整除 ⇨ ∃k∈ℤ 使得 a = b×k

C++实现

bool isDivisible(int dividend, int divisor) {
    if(divisor == 0) throw "Divisor cannot be zero";
    return dividend % divisor == 0;
}

// 测试案例
cout << boolalpha;
cout << "128 % 16: " << isDivisible(128, 16) << endl; // true
cout << "100 % 3: " << isDivisible(100, 3) << endl;   // false

3.2 取整运算类型

类型数学符号C++函数示例(7.8)示例(-7.2)
向下取整⌊x⌋floor()7-8
向上取整⌈x⌉ceil()8-7
向零取整trunc()7-7
四舍五入round()8-7

代码演示

double x = 7.8, y = -7.2;
cout << "floor(" << x << ") = " << floor(x) << endl;
cout << "ceil(" << y << ") = " << ceil(y) << endl;
cout << "trunc(" << x << ") = " << trunc(x) << endl;
cout << "round(" << y << ") = " << round(y) << endl;

4. 因(约)数与倍数体系

4.1 因(约)数分解

  • 因数:若整数 a a a能被整数 b b b整除( a ÷ b a \div b a÷b余数为0),则称 b b b a a a的因(约)数
  • 示例:6的寅数为1, 2, 3, 6
    枚举算法实现
vector<int> factorize(int n) {
    vector<int> factors;
    for(int i=1; i*i<=n; ++i) {  // 优化循环次数
        if(n%i == 0) {
            factors.push_back(i);
            if(i != n/i) factors.push_back(n/i);
        }
    }
    sort(factors.begin(), factors.end());
    return factors;
}

// 示例:36的因数 → [1,2,3,4,6,9,12,18,36]

4.2 倍数判断

  • 倍数:若 a a a b b b的因(约)数,则 b b b a a a的倍数
  • 示例:12是3的倍数
    优化算法
bool isMultiple(long number, long base) {
    return (number >= base) && (number % base == 0);
}

// 验证:isMultiple(150, 15) → true

5. 奇偶性理论

  • 偶数:若某数能被2整除,则该数是偶数
  • 示例:8是偶数
  • 奇数:若某数不能被2整除,则该数是奇数
  • 示例:9是奇数

5.1 基本性质

  • 奇数 + 奇数 = 偶数
  • 偶数 + 偶数 = 偶数
  • 奇数 + 偶数 = 奇数
  • 奇数 × 奇数 = 奇数
  • 奇数 × 偶数 = 偶数

5.2 位运算优化

bool isOdd_Bitwise(int n) {
    return n & 1;  // 二进制最后一位判断
}

bool isEven_Bitwise(int n) {
    return !(n & 1);
}

6. 最大公约数算法

  • 定义:两个数的最大公共约数
  • 示例:gcd(12,18)=6
  • 应用场景:分数化简、密码学

6.1 枚举算法

时间复杂度:O(min(a,b))

实现细节

int gcd_enum(int a, int b) {
    int gcd = 1;
    for(int i=2; i<=min(a,b); ) {
        if(a%i==0 && b%i==0) {
            gcd *= i;
            a /= i;
            b /= i;
        } else {
            ++i;
        }
    }
    return gcd;
}

6.2 更相减损术

算法步骤

  1. a = max ⁡ ( a , b ) ,   b = min ⁡ ( a , b ) a = \max(a,b),\ b = \min(a,b) a=max(a,b), b=min(a,b)
  2. a − b a - b ab替换原 a a a
  3. 重复直到 a = b a = b a=b,此时 a a a为GCD
    特点:中国古代算法,适合小规模计算

迭代实现

int gcd_subtraction(int a, int b) {
    if(a == b) return a;
    while(a != b) {
        if(a > b) 
            a -= b;
        else
            b -= a;
    }
    return a;
}

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

算法步骤

  1. b b b a a a,得余数 r r r
  2. r = 0 r=0 r=0,则 gcd ⁡ ( a , b ) = b \gcd(a,b)=b gcd(a,b)=b
  3. 否则令 a = b ,   b = r a = b,\ b = r a=b, b=r,重复步骤1
    特点:高效,时间复杂度 O ( log ⁡ n ) O(\log n) O(logn)

递归和迭代实现

// 递归版本
int gcd_recursive(int a, int b) {
    return b ? gcd_recursive(b, a%b) : a;
}

// 迭代版本
int gcd_iterative(int a, int b) {
    while(b != 0) {
        int temp = b;
        b = a % b;
        a = temp;
    }
    return a;
}

效率对比
输入:gcd(1071, 462)

  • 枚举法:循环462次
  • 更相减损:21次相减
  • 欧几里得:3次取模

7. 最小公倍数算法

  • 定义:两个数的最小公共倍数
  • 公式 lcm ( a , b ) = ∣ a × b ∣ gcd ⁡ ( a , b ) \text{lcm}(a,b) = \frac{|a \times b|}{\gcd(a,b)} lcm(a,b)=gcd(a,b)a×b
  • 示例:lcm(4,6)=12

7.1 枚举算法

int lcm_naive(int a, int b) {
    int max_val = max(a,b);
    int min_val = min(a,b);
    for(int i=1; ; ++i) {
        int candidate = max_val * i;
        if(candidate % min_val == 0)
            return candidate;
    }
}

7.2 公式法

数学关系
lcm(a,b) = |a×b| / gcd(a,b)

C++实现

int lcm_formula(int a, int b) {
    return abs(a * b) / gcd_iterative(a,b);
}

// 处理大数情况
long long lcm_safe(long long a, long long b) {
    return (a / gcd_iterative(a,b)) * b;  // 避免溢出
}

8. 数系对比

8.1. 数系对比表

数集封闭运算C++类型典型应用领域
自然数加法、乘法unsigned int计数
整数加减乘int温度变化
复数所有代数运算complex电子工程、量子物理

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值