Loading

与神秘伯爵的问候

  • 标题含义为\(GAME\)(博弈论)

博弈论的彻底学习

前言

本文通过大量理论以及例题的学习,彻底掌握博弈题的常用技巧以及分析方法和思路。

序章

对于传统博弈题,常用的思路有四种:打表,分析性质,数据结构,动态规划。
其中分析性质是重中之重。
非传统的博弈题比如二分图博弈,交互式博弈等。

对于大部分博弈题,分析的思路是:
1.先通过一些套路进行转化。
2.转花不了时分析性质。
3.分析性质简化模型,再通过套路维护。

Type 1 有向图游戏

有的博弈是在多个游戏上进行的,有的只需要一个,对于前者,大概率要求出SG函数,对于后者则不尽然。
如果我们只需要判断胜负,我们完全可以给每个状态记录必胜或者必败即可,转移时,如果后继节点有必败态,当前就是必胜,否则就是必败,但是显然大部分题不可能就此停止,因此下一步就是推性质/打表。
游戏图游戏就是在一个有向图上移动棋子判断胜负的过程。

例题 [AGC002E] Candy Piles.

首先简化模型,把所有糖从大到小排序,每次可以取左边一列或者下边一行,取到边界输。
设取了i行,j列的状态为\((i,j)\),那么它由上边和右边的状态推出来。
打表发现除了边界外,每个格子和它右上方的格子的状态是一样,因此可以通过奇偶性直接算出SG函数。
函数的定义是每个状态的后继状态的SG函数,\(mex\),直接计算复杂度很大。

Type 3 Nim游戏

标准Nim游戏

定义

\(n\)堆石子,每次可以取出一堆中的若干个,不能不取,无法操作的获胜。

结论

当且仅当所有石子数异或和为0时必败。

证明

考虑归纳,如果没有棋子,那么异或和为0,必败。
否则,如果当前异或和不为0,我们可以找到异或和最高的1,将其调整到异或和,那么后手的局面异或和为0,根据归纳先手必胜。
如果当前异或和为0,那么不管怎么调整都无法让异或和还是0,而对手则一定可以调整成0,因此先手必败。

K-Nim游戏

定义

\(n\)堆石子,每次可以取出最多k堆中的若干个,不能不取,无法操作的获胜。

结论

当且仅当每一位1的个数被(k+1)整除时必败。

证明

考虑归纳,如果没有棋子,每一位都为0,必败。
否则,从高到低考虑每一位,如果我们把某一堆石子的当前位从0变成1,那么接下来这堆石子的位我们可以任意控制。
对于当前位,如果我们可以控制的位没有达到k,我们可以选当前位是1的石子,控制他们。
否则,是被控制的石子里,有\(a_i\)个1,外面有\(b_i\)个1。
那么我们可以把\(k-a_i\)个0变成1,也就是把1的个数从\(a_i+b_i\)变成\(k+b_i\),那么只要\(b_i\)不为0,我们显然可以取到\(k+1\),而如果\(b_i=0\),我们只需把\(a_i\)变成0即可。
因此一定存在有必胜态到必败态的方法,反之必败态只能到必胜态,因为它使任意位置变成必败至少需要改变\(k+1\)个1。
所以成立

例题 [SDOI2011]黑白棋

考虑把相邻的黑白棋看成一堆石子,那么就是一个\(K-Nim\)游戏。
考虑用总方案减掉不合法方案,设\(dp_{i,j}\)表示考虑前\(i\)为,和为\(j\)的方案数,转移时枚举\((k+1)\)的倍数,乘上组合数即可,最终求答案的时候需要再乘一个插板法。

阶梯Nim游戏

定义

\(n\)堆石子,每次选出一个有至少一个石子的堆,选出至少一个石子移动到前一堆(第1堆前面是第0堆),不能操作者输。

结论

当且仅当奇数位的异或和为0时必败。

证明

考虑只看奇数位置,那么就是一个Nim。
那么当奇数异或和不为0的时,先手显然有Nim的控制权。
而如果后手想打破Nim,也就是把偶数位移到奇数位,那么先手可以再把这些石子移到偶数位,那么先手还有Nim的控制权。

例题 [[SDOI2019]移动金币(https://www.luogu.com.cn/problem/P5363)

和上一题如出一辙,转化为阶梯Nim的计数。
同样减掉不合法方案。
考虑按位\(dp\),设\(dp_{i,j,k,c}\)为前\(i\)位第\(j\)堆总和为\(k\),当前位异或和为0的方案数,复杂度\(O(nm\log n)\)可以通过。
考虑优化,注意到我们要求最终的\(k=n-m\),因此考虑用[HNOI2007]梦幻岛宝珠的方式优化。
最终的\(k\)里每一位是0/1是确定的,为1的话,要么是进位得到的,要么是自己的。
考虑设\(dp_{i,j,k,c}\)为考虑最高的\(i\)位当前到第\(j\)堆,对\(i+1\)的进位\(k\)次,当前位异或和\(c\)的方案数。
也就是说,所有数后\(i\)位的和是\(n\)的后\(i\)位+k\times (1<<i)。
注意到所有数后\(i\)为的和最大是\(2^i \times m\),因此显然\(k\leq m\)
复杂度\(O(m^2\log n)\)

斐波那契Nim

定义

\(n\)个石子,每个人不能去取超过上一个人取的两倍,不能操作的人输。

结论

先手必败当且仅当\(n\)是斐波那契数。

证明

略。

例题 [SNOI2020] 取石子

首先这题是取完的输,我们可以把\(n-1\)变成取完的赢。
那么就是一个限制第一步不超过\(k\)个的斐波那契Nim。
根据斐波那契的证明,获胜当且仅当\(n\)的斐波那契表示的最小位小于等于\(k\)
那容斥一下变成大于\(k\)的方案数,把\(n\)做一下斐波那契分解,做一个数位\(dp\)就好了。

杂题-第一部分

题目1 CF1451FNullify The Matrix

发现不管向右还是向下,对角线编号一定会变。
考虑如果只有一条对角线,那就是个标准Nim,获胜的条件是异或和为0.
现在我们还可以把该对角线后面的对角线都修改。
我们发现,如果某个局面所有对角线异或和都为0,那么一定必败,因为不过操作哪个,在该对角线都会转化到对手的必胜局面,而后面的对角线异或和可以任意改变。
并且,如果某个局面的异或和不为0,我们可以找到第一个不为0的对角线,用标准Nim把该对角线变成0,后面的对角线可以任意操作。
因此获胜的条件时所有对角线异或和都为0.

Type 2 翻硬币模型

描述:每次可以翻转一个黑点或者和它相关的某些点(比如它到根节点链上的点),求SG函数
结论为,每个黑点独立,所以根据性质1,答案为各个黑点的SG函数的异或和,且一般情况下,一个黑点的SG函数都是比较简单的形式。

例题1:ZROJ 20省选集训DAY2T2 一掷千金

简要题意

有一个平面,平面上有一棵树,\((x,y)\)的父亲是\((max(1,x-1),max(1,y-1))\),每次可以反转一个黑点和它的某个祖先之间的点的颜色,求SG函数,且所有黑点以\(k\)个矩形的并的形式给出。

解题思路

通过表,我们可以发现\(SG(x,y)=lowbit(max(x,y))\)
那么把整个平面根据\(y=x\)分成两部分,用类似矩形面积并的方法做扫描线,用线段树维护这一列的黑点的SG函数的异或和。
我们可以发现,\(y=x\)一下,SG函数一样,只需要知道黑点个数即可,而上面每一个位置的SG函数值不变,且我们很容易在\(\log n\)的时间内求出一段区间的\(SG\)函数的异或和,那么我们就可以很方便的通过区间覆盖维护了。
复杂度\(O(n\log^2n)\)

例题2: 某省选模拟赛T2 树论

简要题意

有一个树,每个点有一个棋子,每次挑出一个棋子移向子树中,不能移动的人输。
支持子树加棋子,链加棋子,换跟。

解题思路

同上,我们打表找出每个点的SG函数为它到它子树内最远的叶子的距离。
后面的数据结构部分相当复杂,详见this.

例题3:CF1439E Cheat and Win

解题思路

*3500的题,的确水平很高。
打表发现每个点的SG函数为其2的深度次方,也就是说,后手获胜当且仅当每个深度的点都为偶数个。
我们建出题目给的点的虚树,那么每条虚树边的状态是一样的,可以通过差分向深度打标记。
但是并不好建出虚树,于是我们思考这个题目的性质。
通过打标,我们可以发现,所有符合题目的点呈如下分布:

################
# # # # # # # #
##  ##  ##  ##
#   #   #   #
####    ####
# #     # #
##      ##
#       #
########
# # # #
##  ##
#   #
####
# #
##
#

换句话说,这是一个分形,因此我们可以用分治处理,每次建出一个矩形的虚树。
可以通过递归的方式建出虚树。

CF1434E A Convex Game

又是*3500的题,看起来非常恐怖,但其实是一些套路的堆叠。
答案的SG函数等于各个数组的SG函数异或和。
对于每个数组,有如下引理:

SG函数的最大值是\(O(\sqrt max_{a_i})\)级别的。

因为把转移看成DAG,那么SG函数的值显然小于等于最长路的长度,而因为每次跳的值不降,所以最长路为根号级别。
\(dp_{i,j}\)表示当前到\(i\),上一个是\(j\)的SG值,转移时枚举下一个\(k\)可以做到\(O(n^3)\)
我们可以发现对于每个\(j\),可取的\(k\)是一个后缀,且后缀长度随着\(j\)的减小单调不增。
那么我们从大到小枚举\(j\),就只需要删元素以及查询mex,可以做到\(O(1)\),总复杂度是\(O(n^2)\)

但是我们并没有用到\(SG\)值很小的性质,考虑换一种状态。
\(g_{i,v}\)表示最小的\(j\),满足\(f_{i,j}\leq v\)
同上,我们有\(g_{i,v}\leq g_{i,v-1}\)
考虑怎么转移,因为有上面的性质,所以,若\(g_{i,v-1}\)\(k\)转移,\(g_{i,v}\)也可以通过从\(k\)转移来取到\(SG_i=v-1\),因此我们只需对\(g_{i,v}\),寻找一个\(k\),满足\(f_{k,i}=v-1\)即可。
考虑转移的条件,\(a_k-a_i>a_i-a_{g_{i,v}}\)\(f_{k,i}=v-1\)
前面等价于\(a_{g_{i,v}}>2\times a_i-a_k\),后面等价于\(g_{k,v-1}\leq i<g_{k,v}\)
我们只需找出每个处于后边范围的\(k\)的最大值就行了。
注意到我们是从后向前dp,因此一个位置一旦被某个可行的\(k\)覆盖到,就不会被再次覆盖,因此等价于区间覆盖,用并查集维护。
我们可以从小到大枚举\(j\),维护\(dp\)数组。
时间复杂度\(O(n\sqrt v\log n +n\sqrt n\alpha (n))\),因为值域很小,所以可以预处理大于每个数的第一个位置,去掉\(\log\),但是跑不满,所以这样也能过。

posted @ 2023-02-13 20:39  Larunatrecy  阅读(13)  评论(0)    收藏  举报