基础数论学习笔记
1. 埃氏筛
埃氏筛是一种用于筛选素数的经典算法,通过标记素数的倍数来找出所有小于等于给定数n的素数。
1.1 算法流程
- 初始化一个布尔数组
is_prime,大小为n+1,初始全为true - 将
is_prime[0]和is_prime[1]设为false(0和1不是素数) - 从2开始遍历到√n:
- 如果
is_prime[i]为true,则i是素数 - 将i的所有倍数(从i²开始)标记为非素数(
is_prime[j] = false)
- 如果
- 最后,所有
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)内筛选出所有素数。
算法流程
- 初始化一个布尔数组
is_prime,大小为n+1,初始全为true - 初始化一个空数组
primes存储素数 - 从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]
性质
- 若f是积性函数,且n=p₁ᵃ¹p₂ᵃ²...pₖᵃᵏ,则f(n)=f(p₁ᵃ¹)f(p₂ᵃ²)...f(pₖᵃᵏ)
- 积性函数的狄利克雷卷积仍是积性函数
例题
证明欧拉函数φ(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)
应用
- 计算大指数模运算
- 寻找模逆元
例题
计算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)。
算法流程
基于递归:
- 基础情况:当b=0时,gcd=a,x=1,y=0
- 递归调用exgcd(b, a mod b)
- 更新x和y:
- x_new = y_prev
- y_new = x_prev - (a/b)*y_prev
应用
- 求解线性同余方程ax ≡ c (mod b)
- 求模逆元
例题
求方程123x + 45y = 3的整数解。
解答
使用exgcd:
- 先计算gcd(123,45)=3
- 反向推导:
- 3 = 123 - 2×45 - (45 - 3×13) = ...
- 最终得到x=13, y=-36是一个特解
- 通解为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ₖ
构造解的方法
- 计算M = ∏mᵢ
- 对每个i,计算Mᵢ = M/mᵢ
- 找到yᵢ使得Mᵢyᵢ ≡ 1 (mod mᵢ)(使用exgcd)
- 解为x ≡ ∑aᵢMᵢyᵢ (mod M)
应用
- 大整数计算
- 密码学
- 并行计算
例题
解同余方程组:
x ≡ 2 mod 3
x ≡ 3 mod 5
x ≡ 2 mod 7
解答
- M=3×5×7=105
- 对于第一个方程:
- M₁=35
- 求y₁: 35y₁≡1 mod 3 ⇒ 2y₁≡1 ⇒ y₁=2
- 类似求出y₂=1, y₃=1
- x = 2×35×2 + 3×21×1 + 2×15×1 = 140+63+30=233 ≡ 23 mod 105
- 解为x ≡ 23 mod 105
这份笔记涵盖了数论中几个重要算法和定理的核心内容,包括定义、流程和例题。在实际编程实现时,需要注意边界条件和优化细节。

浙公网安备 33010602011771号