基础数论学习笔记

1. 埃氏筛

埃氏筛是一种用于筛选素数的经典算法,通过标记素数的倍数来找出所有小于等于给定数n的素数。

1.1 算法流程

  1. 初始化一个布尔数组is_prime,大小为n+1,初始全为true
  2. is_prime[0]is_prime[1]设为false(0和1不是素数)
  3. 从2开始遍历到√n:
    • 如果is_prime[i]为true,则i是素数
    • 将i的所有倍数(从i²开始)标记为非素数(is_prime[j] = false
  4. 最后,所有is_prime[i]为true的i都是素数

时间复杂度:\(\mathcal{O}(n\log(\log n))\)

1.2 代码

bool is_prime[N];
memset (is_prime, true, sizeof is_prime);
flag[0] = flag[1] = false;
for (int i = 2; i * i <= n; i++)
	if (flag[i])
		for (int j = i * i; j <= n; j += i)
			flag[j] = true;

1.3 例题

I. Sherlock and his girlfriend

给序列 \(2\sim n+1\) 染色,同时要求每个数和他的质因数的颜色不同。

首先注意到,为使所用颜色尽量少,则所有质数染同一种颜色。
所有质数当然可以染同一种颜色,我们可以令质数的颜色为 \(1\),接下来考虑合数。由于质数已被染上 \(1\),合数的质因子是质数,故合数只要不染 \(1\) 就可以,就让合数染上 \(2\) 就好了。

// Problem: CF776B Sherlock and his girlfriend
// Contest: Luogu
// URL: https://www.luogu.com.cn/problem/CF776B
// Memory Limit: 250 MB
// Time Limit: 1000 ms
//
// Powered by CP Editor (https://cpeditor.org)

/*
    author: Nimbunny
    powered by c++14
*/

#include <bits/stdc++.h>
#define endl '\n'
#define pi pair<int, int>

using namespace std;
const int inf = 0x3f3f3f3f;
const int mod = 1e9 + 7;
const int N = 1e5 + 10;
int n;
bool flag[N];

signed main() {
    cin.tie(nullptr)->sync_with_stdio(false);
    cin >> n;
    flag[0] = flag[1] = 1;
    for (int i = 2; i * i <= n + 1; i++)
        if (!flag[i])
            for (int j = i * i; j <= n + 1; j += i) flag[j] = 1;
    cout << (n < 3 ? "1" : "2") << endl;
    for (int i = 2; i <= n + 1; i++) cout << flag[i] + 1 << " ";
    return 0;
}

2. 欧拉筛(线性筛)

定义

欧拉筛是一种改进的素数筛选算法,可以线性时间复杂度O(n)内筛选出所有素数。

算法流程

  1. 初始化一个布尔数组is_prime,大小为n+1,初始全为true
  2. 初始化一个空数组primes存储素数
  3. 从2遍历到n:
    • 如果is_prime[i]为true,将i加入primes数组
    • 对于每个素数primes[j]
      • 如果i * primes[j] > n,跳出循环
      • 标记is_prime[i * primes[j]] = false
      • 如果i % primes[j] == 0,跳出循环(关键步骤)

时间复杂度

O(n)

优势

每个合数只被标记一次,效率更高

例题

用欧拉筛找出100以内的所有素数。

解答

  • 初始化后,从2开始
  • 2是素数,加入列表,标记4
  • 3是素数,加入列表,标记6,9(3×3后跳出)
  • 4不是素数,标记8(2×4后跳出,因为4%2==0)
  • 继续这个过程直到100

3. 积性函数

定义

积性函数是指对于互质的正整数a和b,满足f(ab)=f(a)f(b)的数论函数。

常见积性函数

  • 欧拉函数φ(n):小于n且与n互质的数的个数
  • 莫比乌斯函数μ(n)
  • 除数函数d(n):n的正因数个数
  • 约数和函数σ(n):n的所有正因数之和

完全积性函数

对于任意a,b(不要求互质)都满足f(ab)=f(a)f(b),如:

  • 幂函数Idₖ(n)=nᵏ
  • 单位函数ε(n)=[n==1]

性质

  1. 若f是积性函数,且n=p₁ᵃ¹p₂ᵃ²...pₖᵃᵏ,则f(n)=f(p₁ᵃ¹)f(p₂ᵃ²)...f(pₖᵃᵏ)
  2. 积性函数的狄利克雷卷积仍是积性函数

例题

证明欧拉函数φ(n)是积性函数。

解答

利用中国剩余定理可以证明:若gcd(a,b)=1,则φ(ab)=φ(a)φ(b)。因为对于模a和模b的剩余系,可以构造一个模ab的剩余系,保持互质性。


4. 欧拉定理

定义

若a与n互质,则aᵠ⁽ⁿ⁾ ≡ 1 (mod n),其中φ(n)是欧拉函数。

特殊情况(费马小定理)

当n为素数p时,φ(p)=p-1,所以aᵖ⁻¹ ≡ 1 (mod p)

应用

  1. 计算大指数模运算
  2. 寻找模逆元

例题

计算7¹⁰⁰ mod 13。

解答

因为13是素数,φ(13)=12
根据欧拉定理,7¹² ≡ 1 mod 13
100 = 8×12 + 4
所以7¹⁰⁰ = (7¹²)⁸ × 7⁴ ≡ 1⁸ × 7⁴ ≡ 7⁴ mod 13
计算7⁴=49²≡10²=100≡9 mod 13


5. 扩展欧几里得算法(exgcd)

定义

扩展欧几里得算法不仅能计算gcd(a,b),还能找到整数x,y使得ax+by=gcd(a,b)。

算法流程

基于递归:

  1. 基础情况:当b=0时,gcd=a,x=1,y=0
  2. 递归调用exgcd(b, a mod b)
  3. 更新x和y:
    • x_new = y_prev
    • y_new = x_prev - (a/b)*y_prev

应用

  1. 求解线性同余方程ax ≡ c (mod b)
  2. 求模逆元

例题

求方程123x + 45y = 3的整数解。

解答

使用exgcd:

  1. 先计算gcd(123,45)=3
  2. 反向推导:
    • 3 = 123 - 2×45 - (45 - 3×13) = ...
    • 最终得到x=13, y=-36是一个特解
  3. 通解为x=13 + 15k, y=-36 - 41k,k∈ℤ

6. 中国剩余定理(CRT)

定义

中国剩余定理解决一组同余方程的问题:
x ≡ a₁ (mod m₁)
x ≡ a₂ (mod m₂)
...
x ≡ aₖ (mod mₖ)
其中m₁,m₂,...,mₖ两两互质

定理内容

存在唯一解x mod M,其中M=m₁m₂...mₖ

构造解的方法

  1. 计算M = ∏mᵢ
  2. 对每个i,计算Mᵢ = M/mᵢ
  3. 找到yᵢ使得Mᵢyᵢ ≡ 1 (mod mᵢ)(使用exgcd)
  4. 解为x ≡ ∑aᵢMᵢyᵢ (mod M)

应用

  1. 大整数计算
  2. 密码学
  3. 并行计算

例题

解同余方程组:
x ≡ 2 mod 3
x ≡ 3 mod 5
x ≡ 2 mod 7

解答

  1. M=3×5×7=105
  2. 对于第一个方程:
    • M₁=35
    • 求y₁: 35y₁≡1 mod 3 ⇒ 2y₁≡1 ⇒ y₁=2
  3. 类似求出y₂=1, y₃=1
  4. x = 2×35×2 + 3×21×1 + 2×15×1 = 140+63+30=233 ≡ 23 mod 105
  5. 解为x ≡ 23 mod 105

这份笔记涵盖了数论中几个重要算法和定理的核心内容,包括定义、流程和例题。在实际编程实现时,需要注意边界条件和优化细节。

posted @ 2025-08-13 22:02  酱云兔  阅读(17)  评论(0)    收藏  举报