基础数论
题单类型:官方题单
创建人:
ACGO官方
题数:21题
收藏题单
完成度:0/21
1. 因子(约数)
1.1 因子的定义
如果整数 能整除 ,也就是存在整数 使得 ,那么称 是 的倍数, 是 的因子(约数),记作:
例如:
1.2 枚举一个数的所有因子
枚举因子常用做法是从 到 试除:
如果 ,那么:
- 是因子
- 也是因子
这样复杂度是 。
参考代码
#include <bits/stdc++.h>
using namespace std;
vector<long long> get_divisors(long long n) {
vector<long long> d;
for (long long i = 1; i * i <= n; i++) {
if (n % i == 0) {
d.push_back(i);
if (i != n / i) d.push_back(n / i);
}
}
sort(d.begin(), d.end());
return d;
}
2. 最大公约数
2.1 定义
表示 和 的最大公约数,即能同时整除 和 的最大整数。
例如:
2.2 欧几里得算法(辗转相除法)
核心结论:
当 时:
复杂度为 ,非常快。
参考代码
long long gcd_ll(long long a, long long b) {
return b == 0 ? a : gcd_ll(b, a % b);
}
2.3 常见性质
- 若 且 ,则
- 时称 互质
3. 质数(素数)
3.1 定义
如果整数 ,并且它只有两个正因子: 和 ,则 是质数。
例如:
- 是质数
- 不是质数
- 不是质数
3.2 试除法判定质数
判定 是否为质数,只需要检查 是否存在因子。
参考代码
bool isPrime(long long n) {
if (n < 2) return false;
for (long long i = 2; i * i <= n; i++) {
if (n % i == 0) return false;
}
return true;
}
4. 埃氏筛
当题目需要求 的所有质数时,可以使用筛法。
4.1 核心思想
- 初始化所有数都假设是质数
- 从 开始遍历
- 如果 是质数,就把它的倍数标记为合数
复杂度约为 。
4.2 参考代码
const int N = 1e6;
bool st[N + 10];
int primes[N + 10];
void f(){
for(int i = 2; i <= N; i++) {
if(st[i]) continue;
for(int j = i + i; j <= N; j += i) {
st[j] = true;
}
}
}
5. 线性筛(欧拉筛)
线性筛可以在 的时间内求出 的所有质数。
5.1 核心思想
每个合数都只会被它的“最小质因子”筛掉一次,因此总复杂度是 。
5.2 参考代码(线性筛 + 最小质因子)
int primes[10000010]; // 存质数表
int idx;
bool st[N]; //记录状态
void f(int n) {
st[1] = true; // true代表不是质数
for(int i = 2; i <= n; i++){
if(!st[i]) {
primes[++idx] = i;
}
//筛的时候 c = a * b a是最小质因子 b是当前数字i
for(int j = 1; primes[j] * i <= n; j++) {
st[primes[j] * i] = true;
if(i % primes[j] == 0) break;
}
}
}
5.3 线性筛的特点
- 时间复杂度
- 可以快速得到所有质数列表
primes - 可以在筛法过程中得到每个数的最小质因子
minp,对分解质因数很有用
6. 唯一分解定理(算术基本定理)
6.1 定理内容
对于任意整数 ,它都可以写成若干个质数的乘积,并且这种分解在不考虑顺序时是唯一的:
其中:
- 是互不相同的质数
- 是正整数
6.2 示例
“唯一”指的是:
如果把 分解成质因数,不管怎么写,最终一定是 (顺序可以变,但质数和指数不会变)。
【前置知识点】
1、数学
【后置衔接知识点】
1、排列组合
【思维导图】

【题目知识点分类】
