博弈论

  • 一.(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版本,改成一张有根图

 把奇环变成 点+边+点,偶环变成点

 原先连在环上的边连在点上

 按树做就行了

原文地址:https://www.cnblogs.com/mikufun-hzoi-cpp/p/12589653.html