0. 前置芝士

定义状态

\(\text{P}\):表示当前局面下先手必败。

\(\text{N}\):表示当前局面下先手必胜。

\(\text{N,P}\) 状态的转移满足如下性质:

  1. 合法操作集合为空的局面为 \(\text{P}\)

  2. 可以移动到 \(\text{P}\) 的局面为 \(\text{N}\)

  3. 所有移动只能到达 \(\text{N}\) 的局面为 \(\text{P}\)

1. 楔子

1.1. 问题

一共有 \(n\) 堆石子,第 \(i\) 堆中有 \(a_i\) 个石子。

每一次操作小 \(\mathtt{G}\) 和小 \(\mathtt{D}\) 可以从任意一堆石子中取出任意数量的石子,至少取一颗,至多取出这一堆剩下的所有石子。

两个人轮流行动,取走最后一个的人胜利。小 \(\mathtt{G}\) 为先手。

1.2. 结论

1.2.1. 内容

对于局面 \((a_1,a_2,...,a_n)\),它是 \(\text{P}\) 局面当且仅当 \(a_1\ \text{xor}\ a_2\ \text{xor}...\text{xor}\ a_n=0\).

1.2.2. 证明

容易发现只要满足以下三个条件即可:

  1. 这个判断将最终态判为 \(\text{P}\) 局面。显然最终态全零。
  2. 根据这个判断被判为 \(\text{N}\) 局面的局面一定可以移动到某个 \(\text{P}\) 局面。设异或和为 \(k\),则一定存在 \(a_i\),其二进制表示在 \(k\) 的最高位上是 \(1\)。由于二进制较高位上的 \(1\) 表示的十进制一定大于位数较低位上的 \(1\) 表示的十进制之和,则 \(a_i\ \text{xor}\ k< a_i\)(异或 \(k\) 也不会影响 \(a_i\) 的更高位)。那么我们将 \(a_i\) 改成 \(a_i\ \text{xor}\ k\),异或和就变成 \(0\) 了。
  3. 根据这个判断被判为 \(\text{P}\) 局面的局面无法移动到某个 \(\text{P}\) 局面。异或和为 \(0\) 只能异或 \(0\) 即取 \(0\) 个石子才能转移到 \(\rm P\) 局面,然而由题设这是不可能的。

2. \(\text{Sprague-Grundy}\) 函数

2.1. 定义

\(\text{ICG}\) 的每个局面看成一个节点,对每个局面和它的子局面连一条有向边。这就转变成了在有向无环图上的移动游戏。

定义节点 \(u\)\(\text{sg}\) 函数为

\[\text{sg}(u)=\text{mex}\{ \text{sg}(v) |v\text{ is a son of }u\} \]

3. \(\text{Sprague-Grundy}\) 定理

3.1. 内容

总游戏的 \(\rm sg\) 函数值为它所包含的 \(n\) 个独立子游戏 \(\rm sg\) 函数值的异或和。

需要注意总游戏的 \(n\) 个独立子游戏与总游戏的子局面之间的区分 —— "局面" 包含多个子游戏,"局面" 才能转移到 "局面"。但是看到后文可能会发现,"子游戏" 这个定义并不重要,许多时候我们甚至找不到一个局面对应的子游戏,更重要的是保证划分出的子局面相互独立。

3.2. 证明

实际上,这可以由上文取石子问题类比过来 —— 总游戏就是所有石子堆,独立子游戏就是一堆石子。对于只剩下一堆石子的局面,定义其 \(\rm sg\) 值为这堆石子的个数(这个意义也是符合递推式的),这样就能推出包含多堆石子的局面的 \(\rm sg\) 值。不过在实际情况中,只用定义局面的 \(\rm sg\) 值即可。

同上文判断方法,我们判断三个条件:

  1. 这个判断将最终态判为 \(\text{P}\) 局面。显然最终态即叶子节点的 \(\rm sg\) 函数值为零。
  2. 根据这个判断被判为 \(\text{N}\) 局面的局面一定可以移动到某个 \(\text{P}\) 局面。这里的子局面就是将某堆石子减少一定数量后得到的所有石子堆。设异或和为 \(k\),则一定存在 \(\text{sg}(u)\),其二进制表示在 \(k\) 的最高位上是 \(1\). 由于二进制较高位上的 \(1\) 表示的十进制一定大于位数较低位上的 \(1\) 表示的十进制之和,则 \(\text{sg}(u)\ \text{xor}\ k< \text{sg}(u)\)(异或 \(k\) 也不会影响 \(\text{sg}(u)\) 的更高位)。那么我们将子游戏 \(u\) 走到 \(\rm sg\) 值为 \(\text{sg}(u)\ \text{xor}\ k\) 的后继,异或和就变成 \(0\) 了。
  3. 根据这个判断被判为 \(\text{P}\) 局面的局面无法移动到某个 \(\text{P}\) 局面。当 \(\text{sg}(u)=0\) 时,不可能存在 \(\text{sg}(v)\) 的值等于零。

可以发现在实际应用中,我们只用保证 "将最终态判为 \(\text{P}\) 局面" 和 "局面所包含的子游戏都是独立的"。其他条件其实在求取 \(\rm sg\) 函数值时就已顺带保证。

4. 例题

上课五分钟后。

\(\rm zy\):"好了新课到这里就结束了,下面我们给几道例题。"

例 1. \(\text{POJ - 2311 Cutting Game}\)

题目大意:有一张 \(n\times m\) 的矩形网格纸,双方轮流操作,对于任意一个局面而言,你可以选择其中一张网格纸,把它剪成两个长宽都是整数的网格纸,率先剪出 \(1\times 1\) 的人获胜,询问先手是否能够获胜。\(n,m\le 200\).

和朴素博弈题不一样,这道题是 "终止态为必胜态"。为了套上 \(\rm sg\) 定理的结论,我们应当定义其他的终止态使其为必败态。

可以发现此题的终止态(为了简单起见,我们只考虑有一个子游戏的局面)实际为 \(\{2,2\},\{2,3\},\{3,2\},\{3,3\}\)(虽然 \(\{3,3\}\) 看上去可以推到 \(\{2,3\},\{3,2\}\),但实际上从 \(\{3,3\}\) 开始必败实际上是因为推到了 \(\{x,y\}\ \ (\min\{x,y\}=1)\),而任何带 \(1\) 的子游戏都是必胜态,不能成为终止态)。

递推就很简单了:

\[\text{sg}(n,m)=\text{mex}\left \{\bigcup_{i=2}^{n-2}\text{sg}(i,m)\oplus\text{sg}(n-i,m)\cup \bigcup_{j=2}^{m-2}\text{sg}(n,j)\oplus \text{sg}(n,m-j)\right\} \]

其中 \(\text{sg}(i,m)\oplus\text{sg}(n-i,m)\)\(\text{sg}(n,m)\) 某一个子局面的 \(\rm sg\) 值。复杂度是 \(\mathcal O(n^3)\) 的。

另外再提一嘴,从这个递推式也可以很好地理解为什么 \(\{3,3\}\) 也是终止态。

由于 \(\rm sg\) 函数的值域牵扯到 \(\rm mex\) 的计算问题,可以预处理的时候打个表看看最大值。反正这题打出来是 \(9\),所以应该算是常数吧(不会证明

例 2. \(\text{[abc206F] Interval Game 2}\)

对于此题,我们可以将局面定义为 \([L,R)\),表示在区间 \([L,R)\) 中填上互不相交的区间的游戏。那么总游戏状态即为 \([1,100)\),终止态就是区间 \([L,R)\) 中没有任何一个可填的区间,显然这也是必败态。

接下来的问题在于是否能将总局面划分成独立子局面。考虑如果选取区间 \([l_i,r_i)\),总游戏状态可以被划分成 \([L,l_i)\cup [r_i,R)\). 此时划分出的两个子局面是独立的。

所以有:

\[\text{sg}(L,R)=\text{mex}\{\text{sg}(L,l_i)\text{ xor sg}(r_i,R)|[l_i,r_i)\subseteq [L,R)\} \]

总复杂度 \(\mathcal O(n^3T)\).

例 3. \(\text{CF850C Arpa and a game with Mojtaba}\)

首先是将数列中的数都进行质因数分解,但问题是,我们并不能将所得幂次简单累加。这里有个 \(\rm observation\):对于一个质数,相同的幂次作用效果相同(废话。这可以极大的减少复杂度,因为 \(a_i\le 10^9\),所以至多也只有 \(30\) 种幂次,我们不妨用一个二进制数来存储这个状态。

由于所有质数都是互不相关的,所以可以将每个质数划分成一个独立子游戏,只要求出每个质数的 \(\rm sg\) 值即可。枚举选取减少的幂次 \(i\),那么可以这样递推:

vis[sg((x>>i)|(x&((1<<i-1)-1))] = true;
posted on 2021-02-15 15:46  Oxide  阅读(166)  评论(0编辑  收藏  举报