想象你是一位社恐的派对主办者,为了让派对显得热闹又不超预算,你决定统计所有可能来的人。第一版名单是从“毽球群”拿到的一份200人名单,第二版名单是从“桌游群”拿到的一份150人名单。这两个群有相当多的人重叠——有些人是既踢毽球又玩桌游的“双重身份者”。如果你直接把两个名单的人数相加,就会发现那些同时出现在两份名单里的人被数了两次。于是你学到了一条生活经验:当两个圈子的名单叠加时,一定要“减掉”那些被重复点名的人。但如果遇到三个圈子,事情就开始变得有趣——三个圈子两两交叠的部分在减法中又被减多了,必须把它们“加回来”。 这个看似简单的“加加减减”的智慧,正是组合数学中赫赫有名的容斥原理。它像一个精明的记账员,通过交替进行“先加、再减、再加、再减……”的操作,精确地统计出一堆彼此重叠的集合中到底有多少个“独特的人”。本篇文章将带你从最直观的两个集合说起,一直走到错排问题、欧拉函数、满射函数计数等高级应用,你会发现,这个“派对记账法”竟然藏在计算机科学的各个角落。
容斥原理是组合计数的三大基本工具之一,掌握它意味着你能优雅处理各种“重叠”问题——从数据库查询优化、概率论推导到密码学中的欧拉定理,它是AI从业者数学直觉的重要一环。
可视化演示
展示容斥原理解决重叠集合计数问题,通过韦恩图、错排问题与欧拉函数三种模式理解交替加减的核心思想。
本节配有交互动效(进入视口后自动加载,约 3KB)。
容斥原理韦恩图 三集合交替加减计数 先加后减再补回交集 |A∪B∪C|=|A|+|B|+|C|-|A∩B|-|A∩C|-|B∩C|+|A∩B∩C|
容斥原理基础
派对主办者把几个圈子的名单叠在一起时,最头疼的事就是“重复”。每个人似乎总有那么几个身份重叠:既是毽球群元老,又是桌游群常客,还可能是烘焙比赛冠军。想要知道“不重不漏”的总人数,主办者必须先理解一个更底层的概念——集合运算:我们把每个圈子想象成一个“箱子”,箱子之间可以有重叠的部分,这份重叠就是交集(取两家名单里共同出现的名字),而所有箱子合在一起就是并集(只要出现在任何一个箱子里就算)。
在数学里,容斥原理关心的是并集的大小。两个集合的并集大小显然不是简单地把各自大小相加,因为交集部分被数了两次。用集合论的记号来表达,对于两个集合 A 和 B,“不重不漏”的并集计数方式为:
回到派对主办者的处境:把毽球群和桌游群合并时,他只需要先相加再减去重叠者,就得到了第一批稳重的来宾预测。这第一步,就是容斥原理这座大厦的第一块砖——两个箱子叠加时,去掉那些“两面派”。
- 符号转译
|A∪B|表示“A 和 B 并集的大小”,也就是两份名单各自的人数相加后去掉重复的最终结果。|A|与|B|分别表示两份独立名单的人数。 - 减去交集
|A∩B|表示两个名单里共同出现的那些名字。由于在|A|+|B|中交集被算到了两次,因此要减去一次。 - 对称美感容斥原理天然具有对称性——你从哪份名单开始“加”,最终结果都一致。正是这种对称性,让它成为组合数学的基石之一。
双集合特例
主办者遇到的第一个简化情况,是只有毽球群(A)和桌游群(B)两个“箱子”。如果两个群完全没有交集(没有一个人同时加两个群),那么公式退化为简单的加法。但如果交集不为空,就必须执行“交叠即减”的操作。
这是最直观的特例:两个集合的并集计数,就是“各自的独立人数相加,再减去重叠的那一群人”。用图形来想,就是两个圆叠在一起,中间那一小块月牙形的重叠区被数了两次,所以我们把它挖掉一次。这个过程可以用一个简单的步骤表达:
更一般地,若存在三个或更多的集合,这个公式可以依次推广。比如三个集合 A、B、C 的并集大小是:
主办者手里有两份名单时,这个特例就像一把直尺,量出重叠,立即减去。双集合特例虽简单,却是理解整个容斥原理“加减交替”节奏的起点。
- 拆分理解先加三个集合各自的大小:
|A|+|B|+|C|,此时某些元素被重复计数。 - 减去成对交集任意两个集合的交集被数了两次,都要减去一次。因此减去
|A∩B|+|A∩C|+|B∩C|。 - 加回三重交集一个元素若同时属于 A、B、C,在第一步被加了 3 次,第二步被减了 3 次,等于没被计入。因此要加上
|A∩B∩C|进行修正。
三集合推广
现在派对主办者收到了第三份名单——烘焙群。三份名单两两重叠,甚至还有三个人同时出现在三份名单里的“超级活跃分子”。如果继续用“先加后减”的思路,主办者会遇到一个微妙的问题:当三个集合 A、B、C 都存在时,|A∩B∩C| 在第二轮减法中被减去了整整三次,而这部分人原本应当在最终并集中被保留。
这正是容斥原理的深层智慧:每一项修正都会引入新的“修正偏差”,于是需要交替地加减,直到最内层的所有交集都被处理干净。那三个集合都喜欢的人,在 |A|+|B|+|C| 中被算了 3 次,又在 |A∩B|+|A∩C|+|B∩C| 中被减了 3 次,于是净计数归零。为了把它救回来,我们必须加回一次 |A∩B∩C|。
三份名单的派对预测,让主办者体会到了“交替加减”的节奏——加一次,减一堆,再加回那个被误伤的“核心团体”。这种交替的意识,很快就会延伸到任意数量的集合。
- 识别全部交集列出 A、B、C 三个集合的所有非空交集:三个单集合、三个双集合、一个三集合。
- 单项符号规律交集中每个元素如果被包含在 k 个集合中,则在并集计数过程中会经历 k 次“加成”与若干次“扣除”。最终符号为
(-1)^(k+1)。 - 从内向外累加对 k=1 到 k=3 逐层相加,即先加单个集合,再减两两交集,最后加三交集。
容斥通用形式
当派对主办者意识到自己可能拥有几十个不同的部门、社群或客户群时,双集合和三集合的手工计算就不再可行。他需要的是一条“统一公式”,不管有多少个箱子,都能按同样的节奏算到底。
容斥原理的通用形式正是为这种场景而生:设我们有 n 个集合 A₁, A₂, …, Aₙ,它们的并集大小可以写成对所有非空子集 S 的交替求和。每一项的符号由子集的大小 |S| 决定:奇数个集合取正,偶数个集合取负。最后的收尾项往往是所有集合的交集(|S| = n 时),因此整个序列以一个清晰的符号结束。
这就像主办者终于请到了一位专业的“派对统计师”,他不再需要蹲在地上一项一项地核对,只需把每个子集对应的重叠人数按“奇正偶负”规则排成一列,一加一减,答案自然浮现。
- 子集遍历公式要求遍历所有非空下标集合 S(共有
2^n - 1个),比如{1}{2}{1,2}…… 一直到{1,2,...,n}。 - 交集大小对每个 S,求这些集合的交集大小
|∩A_i|——也就是同时满足 S 中所有条件的人数。 - 奇偶定符号
(-1)^{|S|+1}意味着当 S 含 1、3、5…个集合时,该子集项取正号;当 S 含 2、4、6…个集合时取负号。
错排问题
派对主办者想把礼物随机分给来宾们,他的要求很特别:每个人都不能拿到写有自己名字的礼物。如果 n 个朋友的礼物被随机打乱,究竟有多少种分配方式能保证“人人拿到的都是别人的礼物”?这种“完全错位”的排列叫做错排。主办者凭直觉意识到,这个问题的答案藏在容斥原理的“排除法”里——先把所有排列都算上,再逐步排除那些有人拿到自己礼物的坏情况。
设 n 个元素的全部排列数为 n!。我们用集合 Aᵢ 表示“第 i 个人拿到了自己的礼物”这一坏事件。那么“没有人拿到自己礼物”的全错排数 Dₙ,就是从总数中排除掉所有 Aᵢ 的并集。这正是容斥原理的经典战场:算出 Aᵢ 的并集大小,再从 n! 中减去,公式推导得到:
派对主办者惊喜地发现,无论来宾有多少,只要随机打乱礼物,保证所有人都拿到别人礼物的概率总是稳定在 36.8% 左右。这份“乱中有序”的奇妙常数,就是错排问题赠送给容斥原理的勋章。
- 总量起点n 个对象的所有排列数是
n!。 - 容斥加权在 n! 基础上,用
(-1)^k/(k!)作为权重对 k 求和。k 代表“至少 k 个固定点”的修正。 - 极限常数当 n 趋向无穷大时,这个交错级数收敛到指数函数 e⁻¹,即 1/e ≈ 0.3679。
欧拉函数
当派对名单上的所有人都换上了从 1 到 n 的数字编号,主办者想统计其中与 n 互素的编号个数——这些编号与 n 没有大于 1 的公因数。这个统计量在数论中叫做欧拉函数 φ(n),它也是密码学中 RSA 算法的重要构件。容斥原理在这里扮演的角色,是从 1 到 n 的完整列表里,逐一剔除那些与 n 共享质因子的“坏编号”。
例如 n = 12,质因子是 2 和 3。我们想统计 1 到 12 中既不能被 2 整除、也不能被 3 整除的数。先用容斥原理:12 中所有数减去 2 的倍数,再减去 3 的倍数,最后加回“既是 2 的倍数又是 3 的倍数”(即 6 的倍数):
派对主办者看着这份编号表,突然觉得容斥原理不只是记人数的工具——它像一台筛子,把“不想要的分子”一层层筛走,只保留那些与 n 互素的忠实宾客。这也正是欧拉函数被称为“筛出来的计数”的原因。
- 质因子提取列出 n 的所有不同质因子 p₁, p₂, …, pₖ(如 12 的质因子为 2、3)。
- 逐项筛选从 n 中减去所有被 p₁ 整除的数,再减所有被 p₂ 整除的数……相当于对每个质因子做一次“去除处理”。
- 连乘积压缩把上面的加加减减用连乘积表达。每个质因子贡献一个因子 (1 − 1/p)。
满射函数计数
如果派对主办者想把 m 件不同的礼物分给 n 个朋友,规则是每位朋友至少得到一件礼物,那么他要统计的就是“满射函数”的数量——每个收到礼物的人都不能空手而归。这是一个更复杂的计数问题,因为礼物是互不相同的,而每位朋友的“名额”没有上限。
满射函数计数的本质,是从所有 m 个礼物到 n 个朋友的函数总数 nᵐ 中,剔除掉那些“至少有一位朋友没有收到礼物”的情况。令 Eᵢ 表示“第 i 位朋友没收到任何礼物”这一坏事件。用容斥原理,逐个排除坏事件,得到:
主办者看着这个公式,回想起自己从“两份名单”一路走到“分礼物”的历程。容斥原理的本质始终如一:从一个“粗略的全体”出发,用交替加减的方式,精确剥离掉所有不需要的情况,直到每一个细节都恰到好处。
- 总映射数m 个礼物各可送给 n 个朋友中的任意一个,因此总数为
n^m。 - 选空手者从 n 位朋友中选 k 位让他们“空手”(收不到任何礼物),方式数为
C(n,k)。 - 剩余分配剩下 n−k 位朋友接收全部 m 个礼物,共有
(n-k)^m种方法。 - 符号修正k 从 0 到 n 交替加减。k=0 是总映射数,k=1 减去至少一人空手,k=2 加回两人空手,依此类推。
应用与编程
容斥原理从派对名单中诞生,却绝不止于派对。在计算机科学里,它到处“兼职”:数据库查询中统计满足多个条件之一的行数时,可以用容斥原理去重;概率论中计算多个事件至少一个发生的概率时,同样可以套用容斥的框架;而欧拉函数更是 RSA 加密算法中密钥生成的核心步骤。主办者把记账经验写成代码,就是希望让计算机也学会这种“先加后减”的智慧。
编程实现容斥原理最直接的方式,是用二进制枚举所有非空子集。比如对于 n 个集合,用一个整数的二进制位表示“选择了哪些集合”,然后按奇偶符号累加交集大小。这是一个广泛应用于算法竞赛、数据去重和概率模拟的可复用套路:
派对主办者终于释然:无论是手动记账还是编写程序,容斥原理的思想始终如一——先把所有可能都纳入,再一重重减去重复,最后把减过头的救回来。这就是“计数不漏”的终极心法。
- 枚举子集
mask从 1 到2^n - 1,覆盖所有非空子集。比如 n=3 时 mask=1,2,3,…,7。 - 计算交集对于每个 mask,找出被选中的集合(对应二进制位为 1 的那些),求它们的交集大小。
- 奇偶定号
popcount(mask)统计 mask 中 1 的个数;奇数为正,偶数为负。
AI 应用场景
数据库多条件统计
阶段:数据预处理与特征工程
解决的问题:在用户行为分析中,常需统计满足至少一个兴趣标签的用户数。传统做法是多次查询再合并,但标签互相重叠导致结果虚高。AI 系统需要精确的“唯一用户数”来训练推荐模型,容斥原理可以保证每个用户只被计数一次。
具体案例:某推荐系统有两个兴趣标签组“科技”和“游戏”,分别命中 5 万和 3.8 万用户,两标签交集 1.2 万。通过容斥公式 5万 + 3.8万 − 1.2万 = 7.6万,得到精确的“至少对一个标签感兴趣”的用户数,训练集大小因此更可靠。
概率计算与事件模拟
阶段:模型评估与不确定性估计
解决的问题:在评估 AI 模型时,常需计算多个失败条件同时出现的概率。如果简单相加各失败率,会高估风险;使用容斥原理的交替加减,可以精确估计“至少一个失败条件发生”的总体概率。
具体案例:自动驾驶感知模块有三个可能导致误判的场景:夜间、雨天、强光,单场景失败率分别为 0.05、0.03、0.02,两两重合 0.005,三重合 0.001。容斥计算得到总失败率 ≈ 0.097−0.011+0.001=0.087,比直接相加的 0.10 更准确地反映了真实风险。
密码学与欧拉函数
阶段:安全通信与加密模块
解决的问题:RSA 加密中需要计算 φ(n) 来决定公私钥。传统试除 1 到 n 逐一检查互素,效率极低。使用容斥原理推导出的欧拉公式,可以在秒级内完成大数的 φ(n) 计算,为加密算法高效生成密钥对。
具体案例:系统生成 RSA 密钥时,选择两个大素数 p、q,令 n = p×q,则 φ(n) = (p−1)(q−1)。该公式正是容斥原理在 n 只有两个质因子时的特例。它让密钥生成从分钟级提速到毫秒级。
Python 演示
# -*- coding: utf-8 -*-"""容斥原理演示:1. 通用并集大小计算(二进制枚举子集)2. 错排数 D_n 计算3. 欧拉函数 phi(n) 计算"""from math import gcd, prod def union_size_intersection(func_intersection, n): """通用容斥原理:并集大小 = 交替加减所有子集交集大小 func_intersection(mask) 返回下标集合 mask 的交集大小 """ total = 0 for mask in range(1, 1 << n): bits = bin(mask).count("1") inter = func_intersection(mask) if bits % 2 == 1: total += inter else: total -= inter return total def derangement(n): """错排数:D_n = n! * sum_{k=0}^{n} (-1)^k / k!""" fact = 1 for i in range(2, n + 1): fact *= i d = 0 for k in range(n + 1): term = fact for i in range(2, k + 1): term //= i d += term if k % 2 == 0 else -term return d def euler_phi(n): """欧拉函数 phi(n):与 n 互素的正整数个数 使用容斥原理: phi(n) = n * prod(1 - 1/p) """ result = n temp = n p = 2 while p * p <= temp: if temp % p == 0: while temp % p == 0: temp //= p result -= result // p p += 1 if temp > 1: result -= result // temp return result def disjoint_union_example(): """用具体集合验证容斥原理(数字集合)""" A = {1, 2, 3, 4, 5} B = {4, 5, 6, 7} C = {5, 7, 8, 9} union = A | B | C # 手工套用容斥公式 calc = len(A) + len(B) + len(C) \ - len(A & B) - len(A & C) - len(B & C) \ + len(A & B & C) print("实际并集大小:", len(union)) print("容斥计算并集:", calc) assert len(union) == calc if __name__ == "__main__": # 直观验证 disjoint_union_example() # 错排数 for n in range(1, 8): print(f"D_{n} = {derangement(n)}") # 欧拉函数 for n in [6, 12, 15, 30]: print(f"phi({n}) = {euler_phi(n)}") # 暴力验证互素个数 brute = sum(1 for x in range(1, n + 1) if gcd(x, n) == 1) assert brute == euler_phi(n) print("所有断言通过,容斥原理实现正确!")
for mask in range(1, 1 << n):用二进制枚举所有非空子集,mask 的每一位代表是否选择对应集合。if bits % 2 == 1: total += inter奇数个集合取正号,偶数个取负号,这就是容斥的“交替加减”。fact预计算 n!,后续每一项都从它出发除以 k!,避免浮点误差。result -= result // p等价于result *= (1 - 1/p),用整数运算消除分数,是容斥在欧拉函数中的实现。while p * p <= temp:只需遍历到 sqrt(n) 即可提取所有质因子,体现算法效率。assert len(union) == calc用实际集合的并集验证容斥公式计算正确。
常见误区
误区我算三个集合并集时,直接用 `|A|+|B|+|C|−|A∩B|−|A∩C|−|B∩C|`,不加回三重交集,感觉减得越干净越好。
正解当存在同时属于三个集合的元素时,它们在三个单集合中总计被加 3 次,又在三个两两交集中被减 3 次,净计数为 0。必须加回 |A∩B∩C| 才算完整。可以想象三张名单里那个三个群都加入的“全勤王”,如果不把他加回来,他就被彻底遗忘了。
为何常见:人脑天然倾向“加法计算、减法修正”,却忽略了修正本身也可能带来新的偏差。这与最初“减少重复”的直觉相冲突,导致初学者忽视三重叠加项。
误区我觉得容斥原理就是 `|A∪B|=|A|+|B|−|A∩B|`,超过两个集合就没法用,或者只能两两套用。
正解容斥原理的真正威力在于通用形式——任意 n 个集合都可以通过“枚举所有非空子集,按奇偶定符号”来计算并集。只要把每个集合看作一个“坏事件”,就能用同样的交替加减法处理错排、欧拉函数等复杂计数问题。认为只能用于双集合,就像是学会了一道菜就以为厨师只会做这道菜。
为何常见:教材通常先讲双集例子再推广,但学生常把最简形式当作全部;另外日常直觉中很少遇到三个以上圈子重叠的场景,所以很难自发推广到 n 个集合。
误区求 n 个人的错排数时,我觉得只要用 `n! − 1` 就行了,因为“至少一个拿到自己礼物”的情况似乎只有一种。
正解“至少一个人拿到自己礼物”的事件远不止一种,因为哪个人拿到自己的礼物有多种选择,而且还有可能两个人同时拿到自己的礼物。错排数必须用容斥原理把所有这些情况都剔除干净,公式 D_n = n!∑(−1)^k/k! 就是“先排除单个固定点、加回双固定点、再减三固定点…”的完整记账。
为何常见:小规模 n=2 或 3 时,"n!−1"恰巧碰对答案,让人误以为规律简单;实际 n=4 时 D₄=9,而 4!−1=23,相差悬殊,直觉被小样本误导。
误区我理解 φ(n) = n∏(1−1/p) 就是把 n 一直除以质因子,不太明白这和容斥原理有什么关系,感觉像独立的数论公式。
正解欧拉函数本质是“从 1 到 n 中排除所有被任意质因子整除的数”。比如 φ(12) 要排除被 2 整除的和被 3 整除的,但 6 的倍数(如 6)被排除了两次,所以要加回一次——这正是双集合容斥。连乘积形式只是把“交替加减”压缩成简洁的乘法外壳。
为何常见:最终公式过于简洁,隐藏了推导过程中层层筛除的细节;学生记住结论却丢失了思想来源,导致遇到变体问题(如求 n 以内且不被任何质因子整除的数的个数)时不会迁移。
面试题
Q1. 容斥原理中,两个集合 A 和 B 的并集大小为 |A|=10、|B|=8、|A∩B|=3,则 |A∪B| 等于多少?
- A.21
- B.18
- C.15← 正确答案
- D.5
答案:C。根据双集合容斥公式 |A∪B| = 10+8−3 = 15。选项 C 正确。选项 B 是把 3 当成了不相交的第三集合;选项 A 是直接相加忘记减交集;选项 D 是误把交集当并集。可以把 10 和 8 想象成两份派对名单,3 人是两边都出现的“双重身份者”,减去一次后才是真正会来的不同人数。
Q2. 三个集合 A、B、C 的并集计算中,为什么最后要加回 |A∩B∩C|?
- A.因为三个集合的交集在第一步没有被加上
- B.因为三重交集在单集合加总中被加了 3 次,又在两两交集中被减了 3 次,净计数为 0← 正确答案
- C.因为交集永远是正数
- D.因为容斥原理规定必须凑成偶数项
答案:B。一个元素同时属于 A、B、C 时,首先在 |A|+|B|+|C| 中被加了 3 次,然后在减去三个两两交集时被减了 3 次,最终等于没被统计。为了不漏掉它,必须加回一次三重交集。这就像三个群都加入的“全勤王”,先被数了三遍,又被删了三遍,最后得靠“加回”救回来。
Q3. 关于错排问题 Dₙ,下列说法正确的有?
- A.Dₙ 表示 n 个人都拿到别人礼物的分配方式数← 正确答案
- B.Dₙ = n!∑(−1)ᵏ/k!← 正确答案
- C.当 n 足够大时,Dₙ/n! 逼近 1/e← 正确答案
- D.Dₙ 等于 n!−1
答案:ABC。A 是错排的定义——人人都拿别人的礼物;B 是容斥原理推导出的标准公式;C 源于级数展开,n→∞ 时 Dₙ/n!→e⁻¹≈0.368;D 错误,n=4 时 D₄=9 而 4!−1=23,说明“至少一人拿自己礼物”的情况远不止一种,必须用容斥细算。
Q4. 用容斥原理计算 1 到 30 中与 30 互素的整数个数,φ(30) 等于多少?
- A.8← 正确答案
- B.10
- C.12
- D.16
答案:A。30 = 2×3×5,容斥计算为 30 − 30/2 − 30/3 − 30/5 + 30/(2×3) + 30/(2×5) + 30/(3×5) − 30/(2×3×5) = 30−15−10−6+5+3+2−1=8。也可以直接用公式 30×(1−1/2)×(1−1/3)×(1−1/5)=8。选项 B 是忘了减 30/5 的结果;选项 C 少算了个质因子;选项 D 是单纯减去除 2、3、5 的倍数但没加回重叠。
Q5. 关于容斥原理的通用形式,以下说法正确的是?
- A.需要对所有非空子集求和← 正确答案
- B.子集大小为奇数时取正号,偶数时取负号← 正确答案
- C.最内层项一定是所有集合的交集← 正确答案
- D.通用形式只适用于两个集合
答案:ABC。通用形式的求和范围是所有非空子集(A 对);符号由子集大小奇偶决定,奇正偶负(B 对);当子集大小为 n 时即所有集合的交集,作为收尾项(C 对);D 错在把通用形式限制为双集合,实际上它处理任意 n 个集合,就像记账员管着几十本名单依然套用同一套加减法则。
Q6. 满射函数计数问题中,将 m 件不同礼物分给 n 个朋友且每位朋友至少一件,如果用容斥原理,第一步应计算什么?
- A.所有分配方式总数 nᵐ← 正确答案
- B.恰好一位朋友空手的方式数
- C.每人恰好一件的方式数
- D.所有朋友都不空手的方式数
答案:A。容斥原理的起点是“全集合”——所有可能的分配方式 nᵐ,然后在此基础上排除“至少一人空手”的坏事件。选项 B、C、D 都是后续修正或最终目标,不是第一步。就像统计派对人数时,先把所有圈子名单相加,再从里面剔除重复。
Q7. 已知 |A|=20, |B|=15, |C|=12, 两两交集分别为 5、6、4,三重交集为 2,则 |A∪B∪C| 为多少?
- A.44
- B.40
- C.34
- D.36← 正确答案
答案:D。代入三集合容斥公式:20+15+12 − 5 − 6 − 4 + 2 = 34。选项 C 正确。选项 A 是 20+15+12−5−6−4 忘记加回三重交集的结果;选项 B 误把三重交集减掉;选项 D 是计算错误。这里可以想象三个社交群,两两重叠的人被各减一次,但三个群都加入的 2 人被减了三次,最后加回一次才准确。
Q8. 关于欧拉函数 φ(n),以下哪些说法是正确的?
- A.φ(n) 计算的是 1 到 n 中与 n 互素的整数个数← 正确答案
- B.若 n = p×q 且 p、q 为不同素数,则 φ(n) = (p−1)(q−1)← 正确答案
- C.φ(n) 的容斥推导过程涉及排除被各质因子整除的数← 正确答案
- D.φ(12) = 4← 正确答案
答案:ABCD。A 是欧拉函数的标准定义。B 是质因数分解后 φ(n)=(p−1)(q−1) 的直接结论。C 描述其容斥本质——先减能被 p₁ 整除的数、再减 p₂ 的倍数、加回 p₁p₂ 的倍数,正是交替加减的筛选过程。D 中 12=2²×3,1 到 12 中与 12 互素的是 1、5、7、11,共 4 个,成立。
Q9. 错排问题中 D₅ 的值是多少?
- A.24
- B.44← 正确答案
- C.48
- D.76
答案:B。D₅ = 5!(1 − 1 + 1/2! − 1/3! + 1/4! − 1/5!) = 120 − 120 + 60 − 20 + 5 − 1 = 44。选项 B 正确。选项 A 是 4!;选项 C 是 5!−5!+60−20 的错误中间结果;选项 D 是计算时忘减最后一项。错排问题就像五个人交换礼物但谁都不能拿自己的,容斥原理逐层修正得到 44 种。
Q10. 容斥原理的典型应用场景包括?
- A.统计多个标签用户去重后的总数← 正确答案
- B.计算错排问题← 正确答案
- C.计算欧拉函数← 正确答案
- D.计算两个集合的笛卡尔积大小
答案:ABC。A 是数据库/推荐系统中的常见应用,多个标签重叠需去重;B 错排数的推导正是容斥原理的经典案例;C 欧拉函数通过排除质因子的倍数来计算互素个数,本质是容斥;D 的笛卡尔积大小是 |A|×|B|,与并集无关,不需要容斥原理。