Sprague-Grundy函数

SG函数

在博弈论中,每个状态可以设为图中的一个节点,每次操作可以认为在图中转移。

mex()函数 :对一个序列操作,返回其中第一个没有出现的自然数 (\(\mathbb{N}\))。

SG函数 :代表每一个局面的状态,如果 \(sg_i=0\) 则必败,否则必胜。

求SG函数:设所有可以转移到状态 \(i\) 的为 \(j\)\(sg_i=mex(sg_j)\)

以bash游戏为例,如果 \(j\) 中没有 \(0\) ,则当前不能使对手失败,\(sg_i=0\) ,必败;否则 \(sg_i\) 不为 \(0\) ,必胜。

SG定理

如果大游戏是由多个独立的小游戏构成,则 \(sg=sg_1 \oplus sg_2 \oplus ... \oplus sg_n\) (总=分异或和)。

分析(类似 Nim游戏):如果各个小游戏都是 \(0\) ,异或和就也是 \(0\) ,此时已经失败了。假设异或和不是 \(0\) ,比如 \(sg_1=7\) ,就说明 \(sg_1\) 的后继 \(0 \sim 6\) 都能取到,可以取任意值且使 \(sg_1\) 减小。作为先手,总是有办法使得最后的总异或和为 \(0\),而后手总是面对总异或和为 \(0\) 的局面,只能使总异或和不为 \(0\) 。因此总异或和为 \(0\) 必败,否则必胜。

例#1 hdu1848 Fibonacci again and again

一共有 \(3\) 堆石子,数量分别是 \(m, n, p\) 个。两人轮流走,每走一步可以选择任意一堆石子,然后取走 \(w\) 个,\(w\) 只能是菲波那契数列中的元素(即每次只能取1,2,3,5,8…等数量)。最先取光所有石子的人为胜者。(\(1 \leqslant n,m,p \leqslant 1000\)

做法:斐波那契数量级较大,小于 \(2^i\)\(3\) 堆石子就是三个小游戏。先求出所有数的 \(sg\) 值(复杂度约为 \(O(n \log n)\)) ,再异或起来判断是否为 \(0\)

例#2 P2148 [SDOI2009] E&D

小 E 与小 W 进行一项名为 E&D 游戏。

游戏的规则如下:桌子上有 \(2n\) 堆石子,编号为 \(1 \sim 2n\)。其中,为了方便起见,我们将第 \(2k-1\) 堆与第 \(2k\) 堆(\(1 \le k \le n\))视为同一组。第 \(i\) 堆的石子个数用一个正整数 \(S_i\) 表示。

一次分割操作指的是,从桌子上任取一堆石子,将其移走。然后分割它同一组的另一堆石子,从中取出若干个石子放在被移走的位置,组成新的一堆。操作完成后,所有堆的石子数必须保证大于 \(0\)。显然,被分割的一堆的石子数至少要为 \(2\)。两个人轮流进行分割操作。如果轮到某人进行操作时,所有堆的石子数均为 \(1\),则此时没有石子可以操作,判此人输掉比赛。

\(1 \le T \le 20\)\(1 \le N \le 2 \times 10^4\)\(N\) 为偶数,\(1 \le S_i \le 2 \times 10^9\)

做法:明显 \(2k-1,\ 2k\) 为一组,求出 \(sg_{i,j}\) 再异或即可求出答案。这是一个注意力题,对前面的 \(sg\) 打表发现 \(sg_{i,j}\)\((i-1)|(j-1)\) 的二进制下第一个 \(0\) 出现的位置。

例#3 P3185 [HNOI2007] 分裂游戏

该游戏的规则是: 共有 \(n\) 个瓶子, 标号为 \(0, 1, \ldots, n-1\),第 \(i\) 个瓶子中装有 \(p_i\) 颗巧克力豆,两个人轮流取豆子,每一轮每人选择 \(3\) 个瓶子,标号为 \(i,j,k\), 并要保证 $i \lt j $ 且 \(j \leq k\),且第 \(i\) 个瓶子中至少要有 \(1\) 颗巧克力豆,随后这个人从第 \(i\) 个瓶子中拿走一颗豆子并在 \(j,k\) 中各放入一粒豆子(\(j\) 可能等于 \(k\)) 。如果轮到某人而他无法按规则取豆子,那么他将输掉比赛。胜利者可以拿走所有的巧克力豆!

两人最后决定由聪聪先取豆子,为了能够得到最终的巧克力豆,聪聪自然希望赢得比赛。他思考了一下,发现在有的情况下,先拿的人一定有办法取胜,但是他不知道对于其他情况是否有必胜策略,更不知道第一步该如何取。他决定偷偷请教聪明的你,希望你能告诉他,在给定每个瓶子中的最初豆子数后是否能让自己得到所有巧克力豆,他还希望你告诉他第一步该如何取,并且为了必胜,第一步有多少种取法?

\(1 \leq t \leq 10\)\(2 \leq n \leq 21\)\(0 \leq p_i \leq 10^4\)

做法:这个题并不是常规的拆解方法。不能按照瓶子拆解,因为移动一个瓶子后会影响其他瓶子。按照每个豆子的位置作为游戏。为了方便,将 \(0 \sim n-1\) 全部倒置。设 \(sg_i\) 为当前豆子在 \(i\) 位置时的局面。讨论后继,拿走当前豆子,会出现两个豆子,放到 \(i\) 前面的位置。可以将分裂拆成两个小游戏,自然 \(sg_i=mex(sg_j \oplus sg_k)\) 。最后,判断 \(p_i\) 奇偶性求最终局面是否必胜。如果先手胜,对 \(i,j,k\) 操作后轮到后手,此时最终 \(sg\) 应为 \(0\)枚举第一步操作的 \(i,j,k\) ,对总 \(sg\) 异或判断是否为 \(0\)

posted @ 2026-08-11 22:39  TanHaoren  阅读(7)  评论(0)    收藏  举报