容斥原理
回顾中学学过的韦恩图(Venn diagram):
将三个集合推广到n个集合,设 U 中元素有 n 种不同的属性,而第 i 种属性称为Pi ,拥有属性Pi的元素构成集合Si 那么:
|n⋃i=1Si|=∑i=1|Si|−∑i<j|Si∩Sj|+∑i<j<k|Si∩Sj∩Sk|−…+(−1)m−1∑ai<ai+1|m⋂i=1Sai|+⋯+(−1)n−1|Si∩⋯∩Sn|=n∑m=1(−1)m−1∑ai<ai+1|m⋂i=1Sai|关于容斥原理的相关知识可以参考:OI Wiki-容斥原理
简单证明一下:设x在k个集合中出现过,则x在上式中被计算的次数:
cnt=C1k−C2k+C3k+⋯+(−1)k−1Ckk又因为:
C0k(−1)k+C1k(−1)k−1+C2k(−1)k−2+⋯+Ckk=−1+cnt=(1−1)k=0所以x在上式中共被计算了一次。
性质:上式有多少项:
C1n+C2n+C3n+⋯+Cnn补一项C0n,则有:
C0n+C1n+C2n+C3n+⋯+Cnn=(1+1)n=2n因此上式中一共有2n−1项。
例题:能被整除的数(Acwing 890)
给定一个整数n和m个不同的质数p1,p2,…,pm。请你求出1~n中能被p1,p2,…,pm中的至少一个数整除的整数有多少个。
数据范围:1≤m≤16,1≤n,pi≤109
暴力做法的时间复杂度是O(mn),一定会超时,考虑用容斥原理做,时间复杂度为O(2m),216=65536<107(每秒大约能算107∼108),以n = 10, m=2, 3为例,集合S2表示能被2整数的数的集合,题目是要求两个集合的并集的元素个数。
|Sp|如何求:|Sp|表示1∼n中p的倍数的个数,即⌊np⌋;|Sp1∩Sp2⋯∩Spk|如何求:因为p1,p2,…,pk是互质的数,所以|Sp1∩Sp2⋯∩Spk|就是1∼n中p1p2…pk的公倍数的个数,即⌊np1p2…pk⌋,计算这一项的时间复杂度就是O(k),则算法总的时间复杂度就是O(2m⋅k)=O(2m⋅m)=O(216⋅16)=O(220)=106。
Tips:枚举2n−1种选法时可以采用位运算的方式,从1∼2n−1枚举i
,把i
看成n位的二进制数,每一位对应一个集合,是1就表示这个集合被选了,是0就表示这一个集合没有被选,因此就可以用二进制数来枚举所有选法了 。确认二进制数的每一位上的数是不是1,就可以用i >> k & 1
。
1 |
|
简单博弈论
首先来看一些相关的定义:
可参考:OI Wiki-博弈论
公平组合游戏ICG:若一个游戏满足:
由两名玩家交替行动
在游戏进程的任意时刻,可以执行的合法行动与轮到哪名玩家无关;
- 不能行动的玩家判负;
则称该游戏为一个公平组合游戏。
NIM博弈属于公平组合游戏,但城建的棋类游戏,比如围棋,就不是公平组合游戏。因为围棋交战双方分别只能落黑子和白子,胜负判定也比较复杂,不满足条件2和条件3。
NIM游戏:给定N堆物品,第i堆物品有Ai个。两名玩家轮流行动,每次可以任选一堆,取走任意多个物品,可把一堆取光,但不能不取。取走最后一件物品者获胜。两人都采取最优策略,问先手是否必胜。
我们把这种游戏称为NIM博弈。把游戏过程中面临的状态称为局面。整局游戏第一个行动的称为先手,第二个行动的称为后手。若在某一局面下无论采取何种行动,都会输掉游戏,则称该局面必败.
所谓采取最优策略是指,若在某一局面下存在某种行动,使得行动后对面面临必败局面,则优先采取该行动。同时,这样的局面被称为必胜。我们讨论的博弈问题一般都只考虑理想情况,即两人均无失误,都采取最优策略行动时游戏的结果。
NIM博弈不存在平局,只有先手必胜和先手必败两种情况。
先手必胜状态与先手必败状态:
先手必胜状态:拿完之后,剩下的状态是必败状态,即可以把当前的状态变成先手必败状态;
先手必败状态:拿完之后,剩下的所有状态都是先手必胜状态。
定理: NIM博弈先手必胜,当且仅当a1⊕a2⊕⋯⊕an≠0 (⊕表示异或)
简单证明一下:
若当前不能进行任何操作,即每堆中物品都是0,0⊕0⊕⋯⊕0=0;
若当前异或值不是0,a1⊕a2⊕⋯⊕an=x≠0,则一定能通过一次操作从某一堆里拿走若干个物品,让剩下的异或值变成0,证明:
设x的二进制表示中最高的一位1在第k位,则在a1∼an中必然存在一个数ai,ai的第k位是1,则有:
ai⊕x<ai那么我们可以从ai这一堆中拿走ai−(ai⊕x),即把ai变成了(ai⊕x),那现在所有数的异或值就变为:
a1⊕a2⊕⋯⊕ai⊕x⋯⊕an=x⊕x=0即证明了若当前异或值不为0,则可以通过一次操作使得剩下的数的异或值为0。
- 若当前的异或值是0,即a1⊕a2⊕⋯⊕an≠0 ,进行任何一次操作后,剩下的数的异或值不会是0,证明:
反证法,若对ai这个堆拿走一些物品后,剩下的个数为a′i,剩下的数的异或值为0,则有:
把上式和原式合起来取异或,则有a_i \oplus a_i’=0,即a_i=a_i’,然而操作必须是要拿走若干物品,不能不拿,即必有a_i’<a_i,因此就矛盾,假设错误,即证。
可见,如果最开始各堆a_i的异或值不是0,先手状态的异或值一定不是0,后手的状态异或值一定是0,则先手必胜;否则若最开始各堆a_i的异或值是0, 则先手必败。
例题1:NIm游戏(Acwing 891)
给定n堆石子,两位玩家轮流操作,每次操作可以从任意一堆石子中拿走任意数量的石子(可以拿完,但不能不拿),最后无法进行操作的人视为失败。问如果两人都采用最优策略,先手是否必胜。
数据范围:1 \le n \le10^5,1 \le 每堆石子数 \le 10^9
1 |
|
例题2:台阶-Nim游戏(Acwing 892)
现在,有一个n级台阶的楼梯,每级台阶上都有若干个石子,其中第i级台阶上有a_i个石子(i≥1)。两位玩家轮流操作,每次操作可以从任意一级台阶上拿若干个石子放到下一级台阶中(不能不拿)。已经拿到地面上的石子不能再拿,最后无法进行操作的人视为失败。问如果两人都采用最优策略,先手是否必胜。
数据范围:1≤n≤10^5, 1≤a_i≤10^9。
考虑一个样例,共三级台阶,每级的石子个数是2,1, 3,则先手有必胜策略。我们先手从第3级拿下1个到第2级,让第1级和第3级的石子都保持一致,都是2个;然后根据对手的操作,我们始终让1,3级台阶的石子个数一致:若对手从第3级往下拿几个,我们就从第一级往下拿几个;若对手从第1级往下拿几个,我们就从第三级往下拿几个;若对手从第2级往下拿几个,我们就从第1级往下拿几个。这样对手看的1,3级台阶石子个数永远是1致的,我看的到永远是不一致的,则对手会先遇到0,0的情况,即我是必胜的。
推广到一般的情况:我们只需要关注奇数级台阶上石子的个数,若其异或值 a_1 \oplus a_3 \oplus \dots\oplus a_n \ne 0 ,则先手必胜;若为0则先手必败。
1 |
|
例题3:集合-Nim游戏(Acwing 983)
给定n堆石子以及一个由k个不同正整数构成的数字集合S。现在有两位玩家轮流操作,每次操作可以从任意一堆石子中拿取石子,每次拿取的石子数量必须包含于集合S,最后无法进行操作的人视为失败。问如果两人都采用最优策略,先手是否必胜。
数据范围:1≤n,k≤100,1≤s_i,h_i≤10000
解这道题前先了解几个概念:
Mex运算:设S表示一个非负整数集合。定义mex(S)为求出不属于集合S的最小非负整数的运算,即:mex(S) = min{x},x属于自然数(从0开始),且x不属于S。
SG函数:在有向图游戏中,对于每个节点x,设从x出发共有k条有向边,分别到达节点y_1, y_2, …, y_k,定义SG(x)为x的后继节点y_1, y_2, …, y_k 的SG函数值构成的集合再执行mex(S)运算的结果,即:
特别地,整个有向图游戏G的SG函数值被定义为有向图游戏起点s的SG函数值,即SG(G) = SG(s)。
有向图游戏的和:设G_1, G_2, …, G_m 是m个有向图游戏。定义有向图游戏G,它的行动规则是任选某个有向图游戏G_i,并在G_i上行动一步。G被称为有向图游戏G_1, G_2, …, G_m的和。
有向图游戏的和的SG函数值等于它包含的各个子游戏SG函数值的异或和,即:
定理:
有向图游戏的某个局面必胜,当且仅当该局面对应节点的SG函数值大于0。
有向图游戏的某个局面必败,当且仅当该局面对应节点的SG函数值等于0。
上面定理证明的思路和第一个Nim游戏是一样的,用SG(x_i)代替a_i即可。
通过SG函数,把n个图的局面通过异或的方式判断出必胜或必败的局面,把指数级的状态(n维)变成1维状态。
(以下图为例,设每次可取的石子数为2,5,共三堆石子,每堆中个数分别为10,7, 5。则求解过程是,把每一堆当作一个有向图游戏,求出每堆的SG值,最后再取异或值SG(10) \oplus SG(7) \oplus SG(5),若结果不为0,则先手必胜,否则先手必败。)
1 |
|
例题4:拆分—Nim游戏
给定n堆石子,两位玩家轮流操作,每次操作可以取走其中的一堆石子,然后放入两堆规模更小的石子(新堆规模可以为0,且两个新堆的石子总数可以大于取走的那堆石子数),最后无法进行操作的人视为失败。问如果两人都采用最优策略,先手是否必胜。
数据范围:1≤n,a_i≤100
拆分—Nim游戏可以用SG函数来做,求出每堆石子的SG值,最后再求异或。对于每一个局面a_i,假设它可以变成局面(b_1, b_2),则它们的SG值的关系为SG(b_1, b_2)=SG(b_1) \oplus SG(b_2)。
1 |
|