- 一.(SG) 函数
定义 (SG(S)=mex(SG(T))),(T) 为 (S) 的后继状态
一般来说,博弈论的许多题都可以把一整个局面分成一个个互不影响的小局面
这样的话有 (SG(S)=SG(T_1) xor SG(T_2)[T_1+T_2=S])
一般来说,(SG) 函数的题遵循一个套路
-
1.设暴力 (dp)
-
2.打表找规律
-
3.AC
这样的题就不细讲了,写几个不寻常的
一棵树,两个人把一个点到根的路径上的点染黑,求 (SG) 函数
考虑一次操作相当于把一个点到根路径上的所有点删掉
那么如果我们处理出来了每个点子树的 (SG) 函数,直接做复杂度 (O(n^2)) 的
考虑处理 (p[u][v]) 表示在 (u) 为根时删掉 (v) 之后的 (SG) 值
考虑这个玩意的转移发现是赋值成某个儿子的 (p) 数组再异或上其他儿子的 (SG) 值
所以我们需要的就是区间异或以及求 (mex)
这个东西可以很容易用字典树维护出来
赋值可以直接字典树合并
先研究一下一层的状态有哪些种
先列举一下 (111,110,011,010,101)
发现 (011,110) 等价,(101,010) 等价
考考虑 (101,010) 都不能继续操作了,可以看成把一个问题分成两个子问题
所以设 (111) 为 (1),(011,110) 为 (0),(0,1) 都可以转化为分界点
可以直接状压了
- 二.(SJ) 定理
先考虑这样一个问题:NIM游戏规定取走最后一个石子为胜,问是否先手必胜
这个问题称为 (Anti-Nim) 游戏
先给结论
1.所有堆石子都只有 (1) 个且 (SG) 值等于 (0) 时先手必胜
2.至少一个堆石子数大于 (1) 且 (SG) 值不等于 (0) 时先手必胜
第一条显然
第二条分类讨论一下
- 1.(SG
eq 0)
若只有一堆大于 (1) 显然必胜,否则显然可以控制是否变成 (SG=0) - 2.(SG=0)
显然至少有两堆大于 (1),那么决策完之后必然至少有一堆大于 (1) 且 (SG eq 0)
然后我们考虑推到一般情况,称为 (Anti-SG) 游戏
(SJ) 定理: (Anti-SG) 游戏先手必胜当且仅当
- 1.游戏的 SG 函数不为 0 且游戏中某个单一游戏的 SG 函数大于 1;
- 2.游戏的 SG 函数为 0 且游戏中没有单一游戏的 SG 函数大于 1
证明太长了不写了,看论文吧
- 三.(NIM) 积
不是很明白。。。先粘个链接
首先定义 (aigotimes b=mex((aigotimes y)igoplus(xigotimes b)igoplus(xigotimes y),(0le x<a,0le y<b)))
大概是在二维 (NIM) 问题上对两维分别做一维 (NIM) 再 (NIM) 积就可以得到二维 (NIM) 的答案
这个玩意有交换律和结合律
然后有一个神奇的东西叫做费马数
定义 (Fermat 2-power) 为 (2^{2^n})
这个玩意有两个性质
- 1.对于费马数 (x) 和 (a<x),有 (xigotimes a=x imes a)
- 2.对于费马数 (x),有 (xigotimes x=frac{3}{2}x)
那么我们算费马数可以考虑分成几个费马数来求
留个板子
展开查看
ll g(int x, int y) {
if (!x || !y) return 1ll << (x | y);
if (~ tab[x][y]) return tab[x][y];
ll res = 1;
Resolve(i, x ^ y) res <<= (1 << i);
Resolve(i, x & y) res = f(res, 3ll << ((1 << i) - 1));
return tab[x][y] = res;
}
ll f(ll x, ll y) {
if (!x || !y) return x | y;
if (x == 1 || y == 1) return max(x, y);
ll res = 0;
Resolve(i, x) Resolve(j, y) res ^= g(i, j);
return res;
}
- 二.杂题
一个 (n imes m) 的网格,右边界和上边界标记了胜负,两个人从左下角出发轮流移动同一枚棋子,问是否先手必胜
结论提
发现除了最外面的两层之外同一对角线的状态相同
直接做就行了
有很多变种,比如右上边界不规则,结论是一样的
N阶NIM
就是有 (k) 堆石子,两个人轮流选至多 (N) 个非空堆,每个堆删去至少一个点,问是否先手必胜
结论题,当且仅当所有 (a_i) 在二进制下的某一位上 (1) 的个数都是 (N+1) 的倍数时先手必胜
阶梯NIM
有 (k) 堆石子,每次选一堆 (i,(i>0)),从第 (i) 堆取任意多个放到 (i-1) 堆,问是否先手必胜
还是结论:当且仅当所有奇数位上的 (a_i) 做 (NIM) 时先手必胜,则该游戏先手必胜
证明挺简单的
假如满足 (NIM) 先手必胜
那么先手一定尽量进行普通 (NIM) 游戏
假如后手想不进行 (NIM) 游戏,那么先手可以把他的操作消除
所以奇数位 (NIM) 先手必胜则阶梯 (NIM) 先手必胜
翻硬币
题目描述: N 枚硬币排成一排,有的正面朝上,有的反面朝上。我们从左开始对硬币按1 到N 编号,
游戏者根据某些约束翻硬币,但他所翻动的硬币中,最右边那个硬币的必须是从正面翻到反面,求给定局面的 (SG) 值
区间翻转显然可以按朝上来分成多个局面
比如 (SG(0110001)=SG(01) xor SG(001) xor SG(0000001))
砍树游戏
给定一棵有根树,每次删掉一条边以及他的子树,不能操作的人输
结论:(SG(x)=(SG[son[x][1]]+1)xor(SG[son[x][k]]+1)xor...xor(SG[son[x][k]]+1))
证明的话画一下转移图大概就懂了。。。吧
ex版本,改成一张有根图
把奇环变成 点+边+点,偶环变成点
原先连在环上的边连在点上
按树做就行了