博弈论小记 更新于 2026/6/30 11:46:54 作者

command_block

博弈论基本框架

  • 公平组合游戏

有一个游戏状态 GG ,某些状态定义为终止态,得到终止态者为负。

玩家的操作可以使得状态发生变化 : GGG\rightarrow G'。 且满足转化关系不存在环 (否则游戏可能一直进行下去)。

满足如下特征 :

  • 两个玩家面对同一个状态 GG ,其可能的目标状态集合是相同的。(决策公平)

  • 两个玩家都知道有关游戏的所有信息。(无隐藏信息)

  • 不包含随机成分。(无随机过程)

  • 只有赢或输,没有平局。(无平局)

一般而言,都约定 : 两个(绝顶聪明的)玩家采取对自己最有利的决策,且轮流作出决策。

  • 必胜态和必败态

先手存在必胜策略的状态 GG ,称之为必胜态,又作 N\rm N 态。

反之称作必败态,又作 P\rm P 态。显然,所有的终止态都是必败态。

若某个态 GG 满足其转移中存在一个 P\rm P 态,则 GGN\rm N 态,因为先手可以把必败态送给对面。

反之,则必然把 N\rm N 态送给对面,此时 GGP\rm P 态。

利用这些基本知识已经可以做一些初等的博弈论题目。

  • 「一堆石子」

    题意 : 有一堆 nn 个石子,对于每个 kk 给出集合 SkS_k ,当还剩 kk 个石子时,拿去石子的个数 cc 必须 Sk\in S_k。 无法操作的人输。问是否先手必胜。

[k][k] 为一堆 kk 个石子的状态。f[k]f[k] 表示 [k][k] 是否为 N\rm N 态。

边界 : f[0]=0f[0]=0

转移 : f[k]=¬mincSkf[kc]f[k]=\neg\min\limits_{c\in S_k}f[k-c]

复杂度为 O(Sk)O(\sum |S_k|) ,本质上是 DAG\rm DAG 上的 DP\rm DP

  • HDU 2897邂逅明下

    题意 : 有一堆 nn 个石子,每次可以拿去 pqp\sim q 个,无法操作的人输。问是否先手必胜。

这是第一题中 Sk=[p,q]S_k=[p,q] 的特殊情况。

对于 [1][p1][1]\sim [p-1] ,为 P\rm P 态。

对于接下来的 [p][p+q1][p]\sim [p+q-1] ,都可以一步到达 P\rm P 态,故为 N\rm N 态。

对于 [p+q][p+q+p1][p+q]\sim[p+q+p-1] ,能到达的范围在 [p][p+q1][p]\sim [p+q-1] 内,故为 P\rm P 态。

如此归纳,不难发现 : 若 nmod(p+q)[1,p]n\bmod (p+q)\in [1,p] 则先手必胜,反之必败。

当然,打表观察也是一个非常好的办法。

  • 带权博弈

游戏中的每种转移方式都有不同的权值,游戏的得分是每一步转移的权值之和。

在首要目标是获胜的前提下,还可能希望最大化/最小化得分。

显然,胜负博弈是带权博弈的子集。

  • 「一堆石子」贰

    题意 : 有一堆 nn 个石子,对于每个 kk 给出二元组集合 SkS_k

    当还剩 kk 个石子时,拿去石子的个数 cc 必须满足 : 存在 (a,b)Sk(a,b)\in S_k ,使得 a=ca=c,且这一步会获得 bb 分。

    在首要目标是获胜的前提下,先手 A 希望最小化得分,后手 B 希望最大化得分。问最终胜负以及得分。

f[k]f[k] 表示 [k][k] 是否为 N\rm N 态。g[k][A/B]g[k][A/B] 为从 [k][k] 开始 A/BA/B 先手的游戏的最终得分。

f[k]=1f[k]=1 即先手必胜 ,则这一步会在所有后继状态 [k][k'] 中选择一个满足 f[k]=0f[k']=0g[k]g[k'] 最好的。

即 $\begin{cases}g[k][A]=\min\limits_{(a,b)\in S_k,f[k-a]=0}g[k-a][B]+b\\g[k][B]=\max\limits_{(a,b)\in S_k,f[k-a]=0}g[k-a][A]+b\end{cases}$

若先手必败,则不设 f[k]=0f[k']=0 的限制。

即 $\begin{cases}g[k][A]=\min\limits_{(a,b)\in S_k}g[k-a][B]+b\\g[k][B]=\max\limits_{(a,b)\in S_k}g[k-a][A]+b\end{cases}$

这是上一题中 Sk={(Prime,1)}S_k=\big\{\big({\rm Prime},1\big)\big\} 的特殊情况。

不同的是,游戏的胜负会影响决策 : 必胜者希望权值小,必败者希望权值大。这反倒统一了两个人的决策。

f[k]f[k] 表示 [k][k] 是否为 N\rm N 态。g[k]g[k] 为从 [k][k] 开始的游戏的最终权值。

f[k]=1f[k]=1 即先手必胜 ,则这一步会在所有后继状态 [k][k'] 中选择一个满足 f[k]=0f[k']=0g[k]g[k'] 最小的。

否则在所有后继状态中取 g[k]g[k'] 最大的。

单次询问复杂度为 O(k=1nπ(k))=O(n2/logn)O\big(\sum_{k=1}^n\pi(k)\big)=O(n^2/\log n)

记落子状态为 GG ,先手方为 TT ,则 (G,T)(G,T) 为一组状态。

考虑如何简洁地表示一种落子状态,不难发现,有子和无子的界限是一条左下到右上的路径,且只能向上或向右。

11 表示向上 00 表示向右,则能用长为 n+mn+m0101 序列来表示某个 GG

本质不同的局面个数为 2×(n+mn)2\times \binom{n+m}{n} 约为 3.7×1053.7\times 10^5 级别。

每个局面的转移为 O(n)O(n) 级别。

unordered_map 记录状态然后记忆化搜索,复杂度即为 O((n+mn)n)O\Big(\binom{n+m}{n}n\Big)

评测记录

SG\bf SG 函数与 SG\bf SG

  • 定义:

    约定终止态的 SGSG 函数值为 00

    定义 mex(S){\rm mex}(S) 为集合 SS 中最小的未出现的自然数。 (要求 SNS\subseteq N)

    GG 能转移到状态集合 TGT_G (转移关系可以看成DAG),那么定义

    SG(G)=mex{SG(V):VTG}SG(G)={\rm mex}\big\{SG(V):V\in T_G\big\}

    人话就是 : 能转移到的状态集合的 SGSG 函数值的 mex\rm mex

  • 性质 : SG(G)=0SG(G)=0GG 是必败态,反之是必胜态。

    SG(G)=0SG(G)=0 ,则代表后继的 SGSG 没有 00 ,反之则代表有 00

    从终止态出发归纳即可证 SG=0SG=0\Leftrightarrow 必败态。

对于单个游戏,SGSG 函数并未给我们带来任何便利。(似乎不能比记录 N/P\rm N/P 态做得更多)

下面我们将看到, SGSG 函数是如何将多个独立的游戏组合到一起的。

  • SG\bf SG

考虑两个人同时面对多个游戏,但每次只能操作其中一个。

把游戏间的并列关系定义为 ++。如 A+BA+B 产生游戏二元组 (A,B)(A,B) ,在一次操作后可能变为 (A,B)(A',B) 或者 (A,B)(A,B') ,类似地可以定义游戏多元组的 SGSG 函数。

(若暂时无法理解并列关系和互相独立的准确意义,可以先看下方“Nim”问题)

定理 : SG(A+B)=SG(A) xor SG(B)SG(A+B)=SG(A){\ \rm xor}\ SG(B)

这给出了游戏合并后的 SGSG 函数与原 SGSG 函数的简洁关系。

证明 : 记 y=SG(A) xor SG(B), G=(A,B)y=SG(A){\ \rm xor}\ SG(B),\ G=(A,B)

等价于证明 $\begin{cases}\forall_{x<y},?_{G\rightarrow G'}SG(G')=x\\\forall_{G\rightarrow G'}SG(G')≠y\end{cases}$ (其实就是把 mex\rm mex 用逻辑语言写出)

由于我们在 DAGDAG 上归纳(边界为终止态),可以认为对于所有的后继状态 GG' ,结论已成立。

  • x<y,?GGSG(G)=x\forall_{x<y},?_{G\rightarrow G'}SG(G')=x

    d=x xor yd=x{\ \rm xor\ }y ,其最高位kk 。设 AA'AA 能转移到的某个状态, 同理有 BB'

    显然 x,yx,y 中必有一个第 kk 位为 11

    xx 的第 kk 位为 11 ,又由于 kk 是最高位, xx 需要把 yy 前面的东西都抵消掉。这样, xxkk 高的部分和 yy 相同,而第 kk 位比 yy 大,与 x<yx<y 矛盾。

    因此,yy 的第 kk 位为 11,故 SG(A),SG(B)SG(A),SG(B) 中必有一个第 kk 位为 11

    不妨设 SG(A)SG(A) 的第 kk 位为 11 ,这样 SG(A) xor dSG(A){\ \rm xor\ }d 会消去第 kk 位,且更高位不变,结果一定会变小。 即 SG(A) xor d<SG(A)SG(A){\ \rm xor\ }d<SG(A)

    这样,由 SGSG 函数的定义,必然存在一个 SG(A)=SG(A) xor d=x xor SG(B)SG(A')=SG(A){\ \rm xor\ }d=x{\ \rm xor\ }SG(B) ( 代入 dd )。

    即存在 SG(A+B)=SG(A) xor SG(B)=xSG(A'+B)=SG(A'){\ \rm xor\ }SG(B)=x

  • GGSG(G)y\forall_{G\rightarrow G'}SG(G')≠y

    若存在 $SG(A'+B)=SG(A'){\ \rm xor\ }SG(B)=SG(A){\ \rm xor\ }SG(B)$ ,则有 SG(A)=SG(A)SG(A)=SG(A') ,矛盾。

不同种类的游戏在求出 SGSG 函数后都能用 SGSG 和来合并。且两个 SGSG 函数相同的游戏在合并时是等价的。

  • Nim\bf Nim

    P2197 【模板】nim游戏

    NN 堆石子,两个人轮流操作,每次可以把某一堆石子拿去若干。没有石子定义为终止态。

    N/PN/P 态的判定方法。

我们先来观察单个堆SGSG 函数。记 [k][k] 为一堆 kk 个石子的状态。

首先,若该堆为空,则为终止态, SG([0])=0SG([0])=0

接下来, [k][k] 可以转移到 [0]...[k1][0]...[k-1] 的任意一个,归纳可证 SG([k])=kSG([k])=k

现在来考虑多堆石子的情况,使用 SGSG 和,异或起来即可判定是否必胜。

至于必胜策略,每次需要将异或和变为 00 给对方。

查看异或和的最高位,选出一个包含该位的数,将这一位置为 00

后面的位无论怎样变化,都会比原来的值小,那么随意安排,把其余非 00 位恰好抵消即可。

例 : 有 $\begin{cases}1010000\\ 0001000\\ 1000010\end{cases}$ , 那么异或和为 00110100011010

所以,选择 10100001010000 来操作,将其变为 10010101001010 异或和就变为 00 了。

  • Take Away\bf Take\ Away

    mm 个石堆,包含 nn 个石子,每一轮可以取走 1...k1...k 个棋子,不能操作者负。

先来考虑单堆。

nkn\leq k 时,总能任意拿,则有 SG(n)=nSG(n)=n

n=k+1n=k+1 时,最近的 00 距离是 k+1k+1 ,无法达到,所以 SG(k+1)=0SG(k+1)=0

然后对于 n=k+1n=k+1 也同样拿不到上一个 11 ,则 SG(k+2)=1SG(k+2)=1

如此可得 SG(n)=nmod(k+1)SG(n)=n\bmod (k+1)

多堆只需求 SGSG 和即可。

  • Hungergame\bf Hungergame

    mm 个箱子,每个箱子中都有若干石子,双人博弈,每一轮可以采取下列操作之一:

    • 打开若干个箱子

    • 将某个箱子中的石子取出若干。

由于可以一次打开多个箱子,这些游戏是不独立的,不能直接套用 SGSG 和。

当所有的箱子都打开的时候,就是经典的 Nim\rm Nim 游戏了。

考虑先手打开什么,若开了异或和不为 00 的箱子集合,相当于送给对面一个 NN 态的 Nim\rm Nim

这样,对面就能逼着你没法操作石子,再开一次箱子。如果每次开完箱子后异或和总是非 00 ,先手必败。

反之,若能开出一个异或和 =0=0 的集合,就可以逼着对面开箱子了。

只需要在第一步开极大的异或和 =0=0 的集合,后手就会沦为前面讲过的那种情况。

所以判别的方法就是 : 是否存在一个集合使得异或和为 00。使用线性基就可以了。

  • Staircase\bf Staircase

    nn 层阶梯,编号 1n1…n,每层阶梯上有一些石子。

    两个玩家轮流操作,每次操作可以将第 jj 层阶梯上若干(至少一个)石头放到 j1j-1 层阶梯上,第 00 层阶梯即为地板。

    将最后一颗石头从阶梯移到地板上的玩家胜利。

不难发现,所有偶数阶梯都等价于垃圾桶。若一方尝试将偶数阶梯中的石子移出(至奇数阶梯),下一个人只需要紧跟着把这些石子丢到下一个(偶数)阶梯即可,最终会到达地板。这个过程中,先后手是不会转换的。

接下来考虑奇数阶梯,一步就可以把任意多的石子丢进垃圾桶,实际上就等价于 Nim\rm Nim 问题。

例题 : P5363 [SDOI2019]移动金币

  • Gra\bf Gra

    m(109)m(\leq 10^9) 个格子排成一行,从左到右编号 1m1…m ,其中 n(105)n(\leq 10^5) 个给定的格子里有硬币,且编号为 mm 的格子里没有硬币。

    两人轮流操作,每次选择一个硬币,移动到它右边第一个不含石子的格子里。

    某个石硬币移动到编号为 mm 的格子的人胜利。

考虑将某个硬币移动到 mm 需要多少步,实际上就是该棋子右侧的空格数。

由此可以想到,将一枚硬币看做大小为 右侧空格数 的石子堆,每次可以拿掉一个,最早将某一堆拿空的人赢。

但是,事情并没有这么简单,当你移动某个棋子的时候,可能会填掉其他一些棋子右侧的一个空位。

手玩能够发现,这样的影响只会发生在“跳过”某一段棋子时。通过选择这一段中谁跳,可以使得大小为 kk一部分石子堆一起变为大小为 k1k-1 的。

这其实很像下阶梯,我们再进行一步转化,可以把某一段硬币视作一个阶梯上的石子堆,就可以等效为 Staircase\bf Staircase

  • Take and Break\bf Take\ and\ Break

    nn 堆硬币 , 编号为 0n10…n-1

    两名玩家轮流取硬币 , 每一轮中 , 选取 33 堆硬币 i,j,ki,j,k ( i<j,jki<j,j≤k )

    ii 中取出一枚,并向 j,kj,k 中各放入一枚 (如果 j=kj=k 则向 kk 中放入 22 枚)。

    不能按上述规则操作的人输。

若将每个位置的硬币堆看做一个子游戏,其两两之间会互相影响。

但是,若把每个硬币看做一个子游戏,不难发现这些游戏两两独立。

可以把在位置 ii 上的硬币看做一堆大小为 mim-i 的石子。

那么,操作的意义就是 : 选取一堆石子,并分裂成两堆比自己小的石子。

这样,就可以对单堆递推出 SGSG 函数值了,复杂度是 O(w3)O(w^3)

[评测记录] ()

  • P5387 [Cnoi2019]人形演舞 | Sol

  • Laskers Nim\bf Lasker's\ Nim

    每次可以从一堆中拿走若干石子,或者将一堆分裂成两个非空石堆。

此时每堆石子是独立的,可以单独分析。

对与状态 [k][k] ,其后继状态可能是 [0]...[k1][0]...[k-1] ,也可以是 [i]+[j] (i+j=k[i]+[j]\ (i+j=ki,j>0)i,j>0) ,共 O(k)O(k) 种。

若值域是 ww ,我们可以 O(w2)O(w^2) 递推出 SGSG 函数值来。然后就做个 Nim\rm Nim 和。

  • 一维翻硬币问题

    nn 个硬币排成一行,有正有反,从左向右按 1n1\sim n 编号。

    按照某种规则选取硬币集合翻转,但是受到操作的最右侧的硬币必须从正面翻到反面(否则转移可能成环)。

    注意到,两个完全相同的游戏在 SG\rm SG 和中会互相抵消,故将反面朝上的硬币翻为正面朝上可以简单地视作多添加了一个同样的反面朝上的硬币而造成抵消。

  • Turning Turtles\bf Turning\ Turtles

    一维翻硬币问题。每次可以选择一枚或两枚硬币翻转,无法操作的玩家输。

可以等价于 Nim\rm Nim 游戏 : 第 ii 个位置的一个硬币等价于大小为 ii 的石子堆。

若单翻 ii 相当于取完一堆。

若翻 i,ji,j ,当 jj 从反面翻到正面时,相当于对某一堆取走了 iji-j 个石子。

jj 从正面翻到反面时,相当于同时删去了大小分别为 i,ji,j 的两堆。

我们能够发现, Nim\rm Nim 游戏中,若有两堆石子相同,则可以同时去掉,不会影响 SGSG 和。

此处也就相当于增加一堆 jj 并与原来有的一个 jj 抵消,和拿去 xyx-y 个石子是等效的。

  • 一维翻硬币问题又一例 : P4077 [SDOI2016]硬币游戏 | Sol

  • Mock Turtles\bf Mock\ Turtles

    一维翻硬币问题。每次可以翻转一个、两个或三个硬币,最右边的硬币必须从正面翻到反面。

奥妙重重。

  • AntiSG\bf Anti-SG

规则和上文中的公平组合游戏略有不同,规定得到终止态的玩家获胜(称之为“ Anti\text{Anti} 规则”)。

此时,两个游戏的和 A+BA+B 仍然会产生游戏二元组 (A,B)(A,B) ,定义其终止态为 (A,B)(A',B') ,当且仅当 A,BA',B' 分别是 A,BA,B 的终止态。

此时, SG(A+B)SG(A+B)SG(A),SG(B)SG(A),SG(B) 之间并没有简洁的关系。但是,仍然存在判断游戏多元组胜负的简便方法。

  • SJ 定理 : 设 G1...mG_{1...m} 为游戏组合中的所有游戏,以 Anti\text{Anti} 规则进行,则先手必胜的充要条件为 :

    • i=1mSG(Gi)0\bigoplus\limits_{i=1}^m SG(G_i)\neq 0maxi=1mSG(Gi)>1\max\limits_{i=1}^m SG(G_i)>1

    • i=1mSG(Gi)=0\bigoplus\limits_{i=1}^m SG(G_i)= 0maxi=1mSG(Gi)1\max\limits_{i=1}^m SG(G_i)\leq1

    两者之一成立。

证明 :

考虑归纳并分类讨论。

  1. i=1mSG(Gi)0\bigoplus\limits_{i=1}^m SG(G_i)\neq 0maxi=1mSG(Gi)>1\max\limits_{i=1}^m SG(G_i)>1\quad 应是 N\rm N 态。

  2. i=1mSG(Gi)=0\bigoplus\limits_{i=1}^m SG(G_i)= 0maxi=1mSG(Gi)1\max\limits_{i=1}^m SG(G_i)\leq1\quad 应是 N\rm N 态。

  3. i=1mSG(Gi)0\bigoplus\limits_{i=1}^m SG(G_i)\neq 0maxi=1mSG(Gi)1\max\limits_{i=1}^m SG(G_i)\leq 1\quad 应是 P\rm P 态。

  4. i=1mSG(Gi)=0\bigoplus\limits_{i=1}^m SG(G_i)= 0maxi=1mSG(Gi)>1\max\limits_{i=1}^m SG(G_i)>1\quad 应是 P\rm P 态。

首先,终止态是 N\rm N 态,其也满足第二个条件。

  1. 若只有一个 SG(Gi)>1SG(G_i)>1 ,则将其操作为 SG(Gi)=0SG(G_i')=011 ,使满足条件 3。

    若有多个 SG(Gi)>1SG(G_i)>1,根据经典 SGSG 理论,可以修改其中一个使得异或和变为 00 ,使满足条件 4。

  2. 将任意一个 SG(Gi)=1SG(G_i)=1 变成 SG(Gi)=0SG(G_i')=0 即可满足条件 3。

  3. 对于任意一个可操作的 GiG_i 都有 SG(Gi)=1SG(G_i)=1。这说明对于所有 GiGiG_i\rightarrow G_i' ,都有 SG(Gi)1SG(G_i')\neq 1

    SG(Gi)=0SG(G_i)=0 ,则满足条件 2。若 SG(Gi)>1SG(G_i)>1 ,则满足条件 1。

  4. 此时不可能只有一个 SG(Gi)>1SG(G_i)>1 ,所以一次操作后仍有 maxi=1mSG(Gi)>1\max\limits_{i=1}^m SG(G_i)>1

    根据经典 SGSG 理论,一次操作后异或和必然非 00 ,则满足条件 1.

直接套用 Anti-SG\text{Anti-SG} 即可。

评测记录

  • Nimk\bf Nim_k

    规则同 Nim\rm Nim ,但是每一轮可以同时操作 1k1…k 个石堆。

此时,游戏之间并不是独立的,不能套用经典的 SGSG 和。

观察普通 Nim\rm Nim ,若仅有两堆相同的石子,则后手总是可以模仿对方的决策,先手必败。

对应到 SGSG 和,即异或值为 00

Nimk\rm Nim_k 中,若仅有 k+1k+1 堆相同的石子,后手总是可以在先手上一轮未操作的堆中模仿对方的决策,先手必败。

可以猜测 Nimk\rm Nim_k 的规则与 k+1k+1 有一定关系。

  • Nim-k 定理 : 设 A1...mA_{1...m} 为各堆石子数目。

    A1...mA_{1...m} 用二进制表示。将这些二进制数直接看做 k+1k+1 进制数,然后做不进位加法。若结果为 00 则先手必败,反之必胜。

    形式化地,记 Ai=j=0gi,j2jA_i=\sum\limits_{j=0}g_{i,j}*2^j,先手必败当且仅当 j,i=1mgi,jmod(k+1)=0\forall j,\sum_{i=1}^mg_{i,j}\bmod(k+1)=0

证明 :

我们暂称上述 k+1k+1 进制不进位加法和为“特征值”。

考虑归纳,终止态的特征值显然为 00

  1. 特征值非 00

    需证能找到一个特征值为 00 的后继。

    考虑和 mod(k+1)\bmod (k+1) 不为 00 的最高位,假设和为 m(k)m(\leq k)

    任意选出 mm 个在该位为 11 的石子堆,并将其这一位置为 00 ,则之后可以随意设置。

    考虑下一个和 mod(k+1)\bmod (k+1) 不为 00 的位,假设和为 rr。设之前选中的 mm 堆石子此时有 aa11bb00

    分类讨论 :

    • ara\geq r ,在 aa11 中选 rr 个变为 00

    • bk+1rb\geq k+1-r ,在 bb00 中选出 k+1rk+1-r 个变为 11

    • a<r,b<k+1ra<r,b<k+1-r ,考虑再征用 rar-a 个为 11 的石子堆。

      这样,操作的总堆数即为 m+ra=a+b+ra=b+r<k+1r+r=k+1m+r-a=a+b+r-a=b+r<k+1-r+r=k+1 ,合法。

      mm 更新为 m+ram+r-a

  2. 特征值为 00

    需证找不到一个特征值为 00 的后继。

    我们最多改变 kk 堆石子,故每一位上 11 的数目变化量是 [k,k][-k,k] 的。

    现在问题是 : 将

    若每一列的变化都为 00 ,则说明每一个 010\rightarrow 1 都对应一个同位的 101\rightarrow 0

    但是,操作只能使得 AA 变小,所以某个 010\rightarrow 1 一定在更高位有一个 010\rightarrow 1

    这样,最高位一定都是 010\rightarrow 1 ,矛盾。

注意, Nimk\rm Nim_k 的结论并不能扩展到一般 SGSG 函数。

设石子数转二进制后视为 k+1k+1 进制做不进位加法得到的和为 SS

先手必胜当且仅当下列两条之一成立 :

  1. 不存在 >1>1 的石堆,且堆数 mod(k+1)1\bmod(k+1)\neq 1

  2. 存在 >1>1 的石堆,且 S0S\neq 0

证明略。

SG\bf SG

  • 二维翻硬币问题

    n×mn\times m 个硬币排成矩阵,有正有反,从左向右按 [1n,1m][1\sim n,1\sim m] 编号。

    按照某种规则选取硬币集合翻转,但是受到操作的最右下侧的硬币必须从正面翻到反面(否则转移可能成环)。

    类似地,翻面操作可以看做新增一枚正面朝上的硬币。

  • Acrostic Twins\bf Acrostic\ Twins

    二维翻硬币问题。每次操作可以翻转两枚硬币,两枚硬币要么同行,要么同列。

类似地,可以把一个硬币看做两堆大小分别为 (x,y)(x,y) 的石子,每次可以从任意一边进行上一个游戏的操作。

不难看出 SG([x,y])=x xor ySG([x,y])=x{\ \rm xor\ }y

  • Turning Corners\bf Turning\ Corners & SG\bf SG 积的定义

    二维翻硬币问题。是每次操作可以翻转某个矩形角上的四个硬币。

并不容易直接看出 SGSG 函数来,考虑暴力打表观察。

f[i,j]f[i,j] 为一个位置为 [i,j][i,j] 的硬币的 SG\rm SG 值。

有 $f[x,y]={\rm mex}\{f[a,b]{\ \rm xor\ }f[a,y]{\ \rm xor\ } f[x,b]:0\leq a<x,0\leq b<y\}$.

(图表来自 @Owaski)

仍然没有发现? 那就对了……几分钟就能看出来的东西也太廉价了吧……

本问题非常经典, SG\rm SG 积的定义和该问题有极大的联系。

SG(G1+G2)SG(G_1+G_2) 记作 G1G2G_1\oplus G_2

对自然数 x,yx,y ,定义 SG\rm SG 积为 :

$$x\otimes y={\rm mex}\{(a \otimes b)\oplus(a\otimes y)\oplus(x \otimes b):0\leq a<x,0\leq b<y\}$$

(即为 f[x,y]f[x,y]

  • SG\bf SG 积的计算

    • 基本运算法则

      不加证明地给出下列运算法则 : (It sounds amazing!)

      xy=yxx\otimes y=y\otimes x x(yz)=(xy)zx\otimes (y\otimes z)=(x\otimes y)\otimes z $$x\otimes (y\oplus z)=(x\otimes y)\oplus(x\otimes z)$$

      观察上表,还可以发现 0x=0, 1x=x0\otimes x=0,\ 1\otimes x=x

      根据这些法则,可以在计算 xyx\otimes y 时进行一系列转化。

      $$12\otimes 9=(8\oplus 4)\otimes (8\oplus 1)=(8\otimes 8)\oplus(8\otimes 1)\oplus(4\otimes 8)\oplus(4\otimes 1)$$

      然后查表,最终答案为 138114=1013\oplus 8 \oplus 11 \oplus 4=10

      一般步骤 : 先将 xyx\otimes yx,yx,y 二进制拆分,然后利用分配律展开,最后得到一系列 22 的幂次的 SG\rm SG 积。

      这样,我们只需解决所有 22 的幂次的 SG\rm SG 积,之后查 O(log2x)O(\log^2 x) 次表即可完成任意 SG\rm SG 积的计算。

      但是,打表的时间消耗仍然非常大。

    • Fermat 2-power

      经过数学家们的努(gao)力(shi),我们现在有两个更加强大的运算法则 :

      定义 Fermat 2-power 为形如 22n,nN2^{2^n},n\in N 的数,集合记为 F2F_2

      对于 xF2x\in F_2 ,对于任意一个 y<xy<x ,有 xy=x×yx\otimes y=x\times yxx=32xx\otimes x=\frac{3}{2}x

      例 : 316=48, 44=63\otimes 16=48,\ 4\otimes 4=6

      现在我们能快速解决 F2F_2 中数的 SG\rm SG 积,但是非 F2F_222 的幂次仍然无法直接解决。

    • 最终计算

      当计算 xyx\oplus yxx22 的幂次时 ,设 G(x,y)=xyG(x,y)=x\otimes y

      找到 aa 满足 22ax<22a+12^{2^a}\leq x< 2^{2^{a+1}} ,令 M=22aM=2^{2a}

      x,yx,y 表示成 x=pM,y=(qM)tx=p\otimes M,y=(q\otimes M)\oplus t

      (其中 p=x/Mp=x/Mss 尽量小)

      $$\begin{aligned} G(x,y) &=(p\otimes M)\otimes\big((q\otimes M)\oplus t\big)\\ &=(p\otimes q\otimes M\otimes M)\oplus(p\otimes t\otimes M)\\ &=\big(p\otimes q\otimes (M\oplus\tfrac{M}{2})\big)\oplus(p\otimes t\otimes M)\\ &=\big(p\otimes q\otimes (M\oplus\tfrac{M}{2})\big)\oplus(G(p,t)\otimes M)\\ &=\big(p\otimes q\otimes M)\oplus(p\otimes q\otimes\tfrac{M}{2}\big)\oplus(G(p,t)\otimes M)\\ &=\big(G(p,q)\otimes M)\oplus G(G(p,q),M/2)\oplus(G(p,t)\otimes M)\\ \end{aligned}$$

      这将 G(x,y)G(x,y) 的计算转化成了 G(p,q),G(G(p,q),M/2),G(p,t)G(p,q),G(G(p,q),M/2),G(p,t) 的计算。

      g(n)g(n) 为计算 G(x,y)G(x,y)x,y22nx,y\leq 2^{2^n} 时的复杂度。

      则有 g(n)=3g(n1)g(n)=3g(n-1) 即 $g(n)=O(3^n)=O\big((\log x)^{\log_2^3}\big)\leq O(\log^2x)$。

      由此,在 O(poly(logw))O({\rm poly}(\log w)) 的预处理之后,即可 O(log2w)O(\log^2 w) 计算 SG\rm SG 积。

  • 游戏的积

在能够快速计算 SG\rm SG 积之后,我们随之解决了 Turning Corners\text{Turning Corners} 问题。

SG\rm SG 和与游戏的和紧密相连。而与 SG\rm SG 积相伴的是另一个概念 : 游戏的积。

给定两个一维翻硬币游戏 G1,G2G_1,G_2 ,定义 G1×G2G_1\times G_2 为一个二维翻硬币游戏,操作如下 :

G1G_1 中翻转 x1,x2xnx_1,x_2\dots x_n 是一个合法操作,G2G_2 中翻转 y1,y2yny_1,y_2\dots y_n 是一个合法操作,那么在 G1×G2G_1\times G_2 中翻转 (xi,yj),i[1,n],j[1,m](x_i,y_j),i\in[1,n],j\in[1,m] 是一个合法操作。

定义 Twin\text{Twin} 为每次必须要翻转两个硬币的一维硬币游戏。

可以发现,Turning Corners\text{Turning Corners} 实质上是两个 Twin\text{Twin} 的积。

  • Tartan Theorem

g1(x)g_1(x) 是编号为 xx 的硬币在 G1G_1 中的 SG\rm SG 函数,类似地有 g2(y)g_2(y)

G1×G2G_1\times G_2 中编号为 [x,y][x,y] 的硬币的 SG\rm SG 值即为 g(x,y)=g1(x)g2(y)g(x,y)=g_1(x)\otimes g_2(y)

比如,若硬币从 00 开始标号,则在 Twin\text{Twin}g(x)=xg(x)=x ,则在 Turning Corners\text{Turning Corners}g(x,y)=xyg(x,y)=x\otimes y

前面我们分析出了若干个独立的游戏组合起来之后的 SG\bf SG 函数值。

现在我们要研究把两个游戏叠加的结果。