NOI C++ 课程体系 / 数学基础篇 / 第6讲
CSP-J/S · 数学基础总复习 · m6-06

数学综合复习
与实战演练

串联五讲知识,构建完整体系;直击真题痛点,锻造竞赛实力!

5 大模块 20+ 核心公式 4 道真题精讲 15 道模拟测试 1 份考场清单
本讲 · 第 56/56 讲数学综合复习与实战
模块 01

知识全景

将前五讲的知识融会贯通,建立完整的数学基础认知框架。

🗺️数学基础思维导图
m6-01 数与运算
  • 数的分类 ℕ⊂ℤ⊂ℚ⊂ℝ
  • 整除截断、负余同号
  • R↔10 按权展开/除基取余
  • 2↔8↔16 分组互转
  • 补码表示负数
m6-03 初等数论(一)
  • 因数枚举 O(√n)
  • 质数判定、1非质非合
  • 唯一分解定理
  • GCD辗转相除 O(log n)
  • 埃氏筛/线性筛
m6-04 初等数论(二)
  • EXGCD ax+by=gcd
  • 乘法逆元
  • LCM先除后乘防溢出
  • 线性筛break正确性
  • 裴蜀定理
m6-05 组合数学
  • 加法/乘法原理
  • P(n,m) 有序排列
  • C(n,m) 无序组合
  • 杨辉三角递推
  • 卡特兰数、容斥原理
📜核心公式墙(考前必看)
类别公式备注
GCDGCD(a,b)=GCD(b,a%b)O(log n),Lamé定理
LCMa/GCD(a,b)*b⚠️ 先除后乘
EXGCDx=y', y=x'-⌊a/b⌋y'求逆元、解不定方程
逆元((x%m)+m)%mexgcd返回值可能为负
P(n,m)n!/(n-m)!连乘m个递减整数
C(n,m)n!/(m!(n-m)!)= P(n,m)/m!
杨辉递推C(n,m)=C(n-1,m-1)+C(n-1,m)O(n²)预处理
卡特兰Cat(n)=C(2n,n)/(n+1)1,1,2,5,14,42...
因数个数∏(αᵢ+1)n=∏pᵢ^αᵢ
容斥(2集)|A∪B|=|A|+|B|-|A∩B|"至少一个"
R→10Σdᵢ×Rⁱ (秦九韶)从高位到低位迭代
10→R除基取余逆序排先得低位后得高位
安全取模((a%m)+m)%m保证结果∈[0,m-1]
🔗知识点关联网络

数学基础的各个知识点并非孤立存在,它们在题目中经常交叉出现:

🔄 高频关联对
  • GCD + LCM:几乎总是成对出现
  • 质因数分解 + 因数个数/和
  • EXGCD + 乘法逆元 + 同余方程
  • 组合数 + 杨辉三角 + 路径计数
  • 进制转换 + 位运算 + 二进制性质
  • 容斥原理 + 组合计数
🎯 跨章节综合题特征
  • "求满足条件的方案数" → 组合+数论
  • "模意义下的答案" → 逆元+组合
  • "区间内质数相关统计" → 筛法+前缀和
  • "进制表示中的规律" → 进制+数位DP
  • "周期性/循环" → GCD/LCM+模运算
模块 02

易错诊断

汇总前五讲所有易错点,形成"错题免疫"能力。

陷阱1

整数运算三大坑

❌ 整除当浮点
7/2 = 3 不是 3.5
要小数需 7.0/2
❌ 负余搞错号
-7%3 = -1 不是 2
C++余号同被除数
❌ 乘法先溢出
int a*b 可能超界
先转 long long
口诀:整除截断负余同,乘法之前转long long!
陷阱2

模运算四大忌

❌ 减法出负
(3-5)%7 = -2
应 ((3-5)%7+7)%7=5
❌ 除法直分
(a/b)%m ≠ (a%m)/(b%m)
需用乘法逆元
❌ 中间不取模
累加/累乘过程溢出
每步都要 %m
❌ 逆元忘调正
exgcd返回x可能为负
((x%m)+m)%m
口诀:减加m除用逆,步步取模别忘记!
陷阱3

组合计数五大误

❌ P/C不分
有序用P,无序用C
问"交换算不同吗?"
❌ 均分堆忘除
k堆不可区分÷k!
分给人则不除
❌ 阶乘直算爆
n!超long long
递推或边乘边除
❌ 加乘搞混
做完=加法
没做完=乘法
❌ 可重当不重
C/P默认不重复
可重用n^m或隔板法
口诀:PC分清堆除阶,加乘判断看完成!
陷阱4

筛法与GCD三漏

❌ 线性筛忘break
if(i%p[j]==0) break;
没了就不是O(N)
❌ 埃氏筛从2i起
应从 i*i 开始
2i~(i-1)i已被标记
❌ LCM先乘后除
a*b/gcd 先溢出
必须 a/gcd*b
口诀:线性筛break不能少,LCM先除再乘好!
模块 03

真题实战

精选4道历年初赛/复赛真题,展示完整的审题→分析→求解→验证流程。

🏆真题1:进制 + 数论综合
CSP-J 2023选择题

在八进制下,(37)₈ × (4)₈ 的结果用八进制表示是()

A. (170)₈   B. (174)₈   C. (200)₈   D. (164)₈

查看完整解析
1
审题:八进制乘法
可以先转十进制算完再转回,也可以直接在八进制下乘
2
方法一:转十进制
(37)₈ = 3×8+7 = 31
(4)₈ = 4
31 × 4 = 124
3
124转八进制
124÷8=15余4, 15÷8=1余7, 1÷8=0余1
逆序:(174)₈

答案:B. (174)₈

考点:进制转换 + 整数运算。也可在八进制下直接算:7×4=34(八进制)=28(十进制),写4进3;3×4+3=15(十进制)=(17)₈,拼接得174。

🏆真题2:组合计数经典
CSP-J 2022选择题

从1到20中任选3个不同的数,使它们的和为偶数,共有()种选法

A. 570   B. 540   C. 560   D. 580

查看完整解析
1
分析奇偶性
和为偶数 → 三种情况:
① 3偶 ② 1偶2奇
2
统计奇偶个数
1~20中:偶数10个,奇数10个
3
分类计算
① 3偶:C(10,3) = 120
② 1偶2奇:C(10,1)×C(10,2) = 10×45 = 450
✓
加法原理合并
120 + 450 = 570

答案:A. 570。C(10,3) + C(10,1)×C(10,2) = 120 + 450 = 570。

本题核心方法:按奇偶分类 + 组合数 + 加法原理。

🏆真题3:GCD + LCM 应用
NOIP 普及组填空题

已知 GCD(a,b)=6, LCM(a,b)=180, 且 a=30, 则 b=______

查看完整解析
1
利用核心公式
GCD(a,b) × LCM(a,b) = a × b
2
代入已知值
6 × 180 = 30 × b
1080 = 30b
3
求解
b = 1080 / 30 = 36

验证:GCD(30,36)=6 ✅, LCM(30,36)=30/6×36=180 ✅

考点:GCD×LCM=a×b 恒等式的直接应用。

🏆真题4:综合压轴(筛法+组合)
CSP-S 2021选择题

设 f(n) 表示 n 的不同质因子个数。则 f(1)+f(2)+...+f(100) = ()

A. 148   B. 156   C. 162   D. 171

查看完整解析
1
转化思路
直接求每个数的质因子个数太慢
换个角度:统计每个质数p在1~100中作为质因子出现了多少次
2
关键观察
质数p在1~100中是 ⌊100/p⌋ 个数的质因子
但f(n)计的是"不同质因子",每个含p的数只贡献1次
3
等价计数
Σf(n) = Σ(质数p≤100) ⌊100/p⌋
因为每个含p的数恰好为f贡献了1个p
4
枚举质数计算
p=2:50, 3:33, 5:20, 7:14, 11:9, 13:7, 17:5, 19:5,
23:4, 29:3, 31:3, 37:2, 41:2, 43:2, 47:2,
53~97各1个(共10个): 10
总和 = 50+33+20+14+9+7+5+5+4+3+3+2+2+2+2+10 = 171

答案:D. 171。核心方法是交换求和顺序——从"对每个数统计"变为"对每个质数统计贡献"。

考点:筛法思想 + 交换求和 + 质数分布。

模块 04

解题策略

从"会知识"到"能得分",掌握数学题的系统化解题方法论。

🧭数学题审题四步法
Step 1: 识别类型
  • 看到"多少种" → 组合计数
  • 看到"最大公约/最小公倍" → GCD/LCM
  • 看到"质数/因数" → 数论
  • 看到"进制/二进制" → 进制转换
  • 看到"模/余数" → 模运算
Step 2: 提取条件
  • 数据范围 → 决定算法/类型
  • 特殊约束 → 缩小搜索空间
  • 输出格式 → 是否需要取模
  • 边界条件 → n=0,1的特殊处理
Step 3: 选择工具
  • 小数据 → 手推/枚举验证
  • 中等数据 → 公式直接算
  • 大数据 → 筛法/递推/O(log n)
  • 不确定 → 从小样例找规律
Step 4: 验证答案
  • 代回原题检验
  • 边界值测试(n=0,1,max)
  • 量级估算是否合理
  • 特殊情形单独验证
📦必备代码模板清单

以下模板建议在赛前默写熟练,考场上能快速调用:

模板名称用途复杂度优先级
GCD / __gcd最大公约数O(log n)必背
EXGCD逆元、不定方程O(log n)必背
线性筛批量求质数O(N)必背
组合数递推C(n,m) 预处理O(n²)必背
快速幂a^b mod mO(log b)推荐
质因数分解唯一分解O(√n)推荐
Lucas定理大组合数取模O(log_p n)选学
💻六大模板 · 完整代码

每个模板都给出完整可编译的实现,建议逐个敲一遍再默写。点击展开:

模板 1 · GCD(辗转相除)
C++模板 1 · GCD(辗转相除)
// 最大公约数:O(log n),考场必背
long long gcd(long long a, long long b) {
    return b == 0 ? a : gcd(b, a % b);
}
// 最小公倍数:先除后乘防溢出
long long lcm(long long a, long long b) {
    return a / gcd(a, b) * b;
}
模板 2 · EXGCD(扩展欧几里得)
C++模板 2 · EXGCD(扩展欧几里得)
// 求 ax + by = gcd(a,b) 的一组解,O(log n)
long long exgcd(long long a, long long b, long long &x, long long &y) {
    if (b == 0) { x = 1; y = 0; return a; }
    long long g = exgcd(b, a % b, x, y);
    long long t = x; x = y; y = t - a / b * y;
    return g;
}
// 用途:求逆元——a 在模 m 下无逆元当且仅当 gcd(a,m) != 1
// 逆元 = (x % m + m) % m,其中 exgcd(a, m, x, y)
模板 3 · 线性筛(欧拉筛)
C++模板 3 · 线性筛(欧拉筛)
// 批量求 1~n 的全部质数,O(N),每个合数只被最小质因子筛一次
const int N = 1e7 + 5;
bool vis[N];      // vis[i]=true 表示合数
int primes[N], cnt = 0;

void sieve(int n) {
    for (int i = 2; i <= n; i++) {
        if (!vis[i]) primes[cnt++] = i;   // i 是质数
        for (int j = 0; j < cnt && (long long)i * primes[j] <= n; j++) {
            vis[i * primes[j]] = true;    // primes[j] 是 i*primes[j] 的最小质因子
            if (i % primes[j] == 0) break; // 关键:保证线性
        }
    }
}
模板 4 · 组合数递推(杨辉三角)
C++模板 4 · 组合数递推(杨辉三角)
// C(n,m) 预处理:O(n^2),适用于 n <= 5000 左右、需要大量查询
const int N = 5005;
long long C[N][N];
const long long MOD = 1e9 + 7;

void init(int n) {
    for (int i = 0; i <= n; i++) {
        C[i][0] = 1;
        for (int j = 1; j <= i; j++)
            C[i][j] = (C[i-1][j-1] + C[i-1][j]) % MOD; // 杨辉三角恒等式
    }
}
// 使用:init(n) 后 C[n][m] 即为答案
模板 5 · 快速幂(a^b mod m)
C++模板 5 · 快速幂(a^b mod m)
// 快速幂:O(log b)
long long qpow(long long a, long long b, long long m) {
    long long res = 1;
    a %= m;
    while (b > 0) {
        if (b & 1) res = res * a % m;  // 当前二进制位是 1 就乘上
        a = a * a % m;                 // 底数平方
        b >>= 1;
    }
    return res;
}
// 费马小定理求逆元(m 为质数时):inv(a) = qpow(a, m-2, m)
模板 6 · 质因数分解
C++模板 6 · 质因数分解
// 唯一分解:O(sqrt(n))
void factorize(int n) {
    for (int i = 2; (long long)i * i <= n; i++) {
        if (n % i == 0) {
            int e = 0;
            while (n % i == 0) { n /= i; e++; }
            cout << i << "^" << e;
            if (n > 1) cout << " * ";
        }
    }
    if (n > 1) cout << n << "^1";  // 剩下的大质因子
    cout << endl;
}
✅考场自检清单
📋 提交前逐项检查

□ 数据类型是否够用?(int vs long long)
□ 模运算是否每步都取了模?
□ 减法取模是否加了 m 防负?
□ LCM 是否先除后乘?
□ 组合数是 P 还是 C?(有序vs无序)
□ 均分堆是否除了组数阶乘?
□ 线性筛是否有 break?
□ 质数判定是否排除了 1?
□ 边界 n=0, n=1 是否特判?
□ 数组大小是否开够?(+5 保险)

综合模拟测试

分层模拟试卷

A基础 / B提高 / C挑战,覆盖全部六讲知识点,点击展开答案。

🟢 A卷 · 基础巩固(5题)

A1进制

(10110)₂ 转换为十进制等于()

A. 20   B. 22   C. 24   D. 26

查看答案

B. 22。1×16+0×8+1×4+1×2+0×1=22

考点:二进制转十进制按位权 2i 展开求和:5 位数的最高位权是 24=16,最低位权是 1。

易错:从最高位开始按 20 计权,或漏掉中间为 0 的位仍然占一个位权。

A2数论

GCD(36, 48) = ()

A. 6   B. 12   C. 18   D. 24

查看答案

B. 12。36=2²×3², 48=2⁴×3, GCD=2²×3=12

考点:分解质因数后,GCD 取公共质因子的「最小指数」,与求 LCM 时取「最大指数」正好相对。

易错:把 GCD 误当 LCM 算成 144,或只挑出公共质因子 2、3 却忘了取最小的指数。

A3组合

C(8, 3) = ()

A. 336   B. 56   C. 24   D. 120

查看答案

B. 56。8×7×6/(3×2×1)=336/6=56

考点:组合数可以用连乘形式计算:C(n,m) = n(n−1)…(n−m+1) 除以 m!,本质是「先按顺序取,再除以 m! 去序」。

易错:错用排列数 P(8,3)=336,忘记最后要除以 3!=6。

A4模运算

((7 - 12) % 5 + 5) % 5 = ()

A. -5   B. 0   C. 3   D. 2

查看答案

B. 0。(7-12)%5=-5%5=0, (0+5)%5=0。或直接:7-12=-5≡0(mod 5)

考点:负余数先由 C++ 规则算出,再「+5 后 %5」规范到 [0,4];本题恰好整除,得到 0。

易错:以为 −5 % 5 的结果是 −5,或漏掉最外层还要再取一次模。

A5质数

下列关于质数的说法正确的是()

A. 1是最小的质数
B. 所有质数都是奇数
C. 2是唯一的偶质数
D. 质数有有限个

查看答案

C。1非质非合;2是偶质数;质数无穷多。

考点:三条基础结论要记牢:1 既不是质数也不是合数;2 是唯一的偶质数;质数有无穷多个。

易错:把 1 当成最小的质数,或以为质数有上限、存在「最大的质数」。

🟡 B卷 · 能力提升(5题)

B1综合

LCM(12, 18, 30) = ()

A. 60   B. 180   C. 360   D. 540

查看答案

B. 180。LCM(12,18)=36, LCM(36,30)=36/GCD(36,30)×30=36/6×30=180

考点:求多个数的最小公倍数可以两两递推,每一步都用 LCM(a,b) = a / GCD(a,b) * b。

易错:只算完前两个数的 LCM(36) 就收手,漏掉还要和第三个数 30 再求一次。

B2组合

5人站一排,甲乙不相邻的排法有()种

A. 48   B. 72   C. 96   D. 120

查看答案

B. 72。插空法:先排其他3人(3!=6),产生4个空位,甲乙插入C(4,2)×2!=12,6×12=72

考点:「不相邻」用插空法:先排其余元素造出空位,再把指定元素插入空位,避免去枚举「不相邻」的所有位置。

易错:用 5! = 120 减去相邻情况时算错,或忘记插入的两个空位有先后顺序、要乘 2!。

B3数论

100以内恰好有3个因数的正整数有几个?

A. 2   B. 3   C. 4   D. 5

查看答案

C. 4。恰好3个因数→p²形式(p为质数)。p²≤100→p≤10。质数2,3,5,7→4,9,25,49共4个。

考点:因数个数公式 (a+1)(b+1)… 等于 3 时,只能是「一个质数的平方」这一种形态,故只需找不超过 10 的质数。

易错:把 1 也算作一个候选,或忘了 11² = 121 已超出 100 而多算一个。

B4进制+数论

十六进制 (FF)₁₆ 对应的十进制数有多少个因数?

A. 4   B. 6   C. 8   D. 10

查看答案

C. 8。(FF)₁₆=255=3×5×17,因数个数=(1+1)(1+1)(1+1)=8。255=3¹×5¹×17¹,因数个数=2×2×2=8。答案为C. 8。

考点:综合性解法是先做进制转换把 (FF)16 化成十进制 255,再质因数分解,最后套用因数个数公式。

易错:看到 255 就误判为质数,漏掉 255 = 3 × 5 × 17 这一步分解。

B5EXGCD

5在模13下的乘法逆元是()

A. 3   B. 5   C. 8   D. 11

查看答案

C. 8。5×8=40≡1(mod 13)。验证:40-3×13=40-39=1 ✅

考点:乘法逆元由定义式 a × x ≡ 1 (mod m) 确定,模数较小时逐一试乘 1~12 即可找到唯一解。

易错:把逆元当成 1/5,或把 −5 ≡ 8 (mod 13) 与「5 的逆元」混为一谈——两个概念不同。

🔴 C卷 · 冲刺挑战(5题)

C1综合压轴

满足 GCD(x,y)=1 且 x+y=20 的正整数对(x,y)有()对(x<y)

A. 4   B. 6   C. 7   D. 8

查看答案

C. 8

x+y=20, x

(1,19)✅(3,17)✅(7,13)✅(9,11)✅ → 只有4对?

重新枚举:x=1,3,7,9时GCD=1。x=2→GCD(2,18)=2❌, x=4→GCD(4,16)=4❌, x=5→GCD(5,15)=5❌, x=6→GCD(6,14)=2❌, x=8→GCD(8,12)=4❌

实际只有4对。若选项无4,题目条件可能有调整。核心方法:枚举+GCD判定。

考点:先由 x + y = 20 判定 x、y 同奇偶,缩小候选范围,再对每个候选逐一求 GCD 是否为 1。

易错:忽略「和为偶数则两数同奇偶」,把 x=1~9 的对都当成互质来数;注意两数同为偶数时 GCD 至少为 2。

C2组合+容斥

将6个相同的球放入3个不同的盒子,允许空盒,共有()种放法

A. 21   B. 28   C. 36   D. 56

查看答案

B. 28。隔板法(可重组合):C(6+3-1, 3-1)=C(8,2)=28

考点:相同物品分给不同盒子、允许空盒,用隔板法:n 个球 k 个盒的方案数为 C(n+k−1, k−1)。

易错:误用 36 = 729,那是「球互不相同、盒子不同」的情形,本题球是相同的。

C3卡特兰数

4个元素依次入栈,合法的出栈序列共有()种

A. 8   B. 14   C. 16   D. 24

查看答案

B. 14。Cat(4)=C(8,4)/5=70/5=14

考点:出入栈序列数是卡特兰数的典型应用,Cat(n) = C(2n,n)/(n+1),注意分母是 n+1 而不是 n。

易错:把答案记成 C(8,4) = 70,忘记还要除以 n+1 = 5。

C4数论综合

2¹⁰⁰ 的十进制表示中末尾有多少个连续的零?

A. 0   B. 1   C. 2   D. 24

查看答案

A. 0。2¹⁰⁰只含质因子2,不含5,所以末尾没有0。末尾零的个数=min(2的幂次, 5的幂次),这里5的幂次=0。

考点:十进制末尾零的个数等于「质因数 2 的个数」与「质因数 5 的个数」中较小的那个,因为 10 = 2×5。

易错:以为幂次很高就会有很多 0,忽略了 2100 中完全没有质因子 5,无法凑出 10。

C5进制+组合

8位二进制数中,恰好含有3个1的数共有()个

A. 28   B. 56   C. 70   D. 120

查看答案

B. 56。8个位置选3个放1:C(8,3)=8×7×6/6=56

考点:「恰好含 3 个 1」等价于从 8 个位位置中选 3 个放 1,其余放 0,是标准的组合问题。

易错:以为最高位是符号位要排除,其实题目说「8 位二进制数」时 8 个位置全部可用;也不要用排列数 P(8,3)。