20200315 博弈笔记

棋盘对角线状态:

在这里插入图片描述
暴力的做法是 O ( n m ) O(nm) O(nm)的。
用bitset按照斜对角线一条一条的做是 O ( n m / w ) O(nm/w) O(nm/w)的。
结论:对于 i , j ≥ 3 i,j\ge3 i,j3,有 f [ i ] [ j ] = f [ i − 1 ] [ j − 1 ] f[i][j]=f[i-1][j-1] f[i][j]=f[i1][j1]。即从第三行第三列开始每个点与对角线上的前一个点相同。通过反证法可简单证明。
于是求出第二行第二列之后就可以 O ( 1 ) O(1) O(1)得出任意一点的状态。

应用:AGC 002 E(注意此题是吃最后一颗糖的输)

应用:
在这里插入图片描述
f [ l ] [ r ] = ! ( f [ l + 1 ] [ r ] & f [ l ] [ r − 1 ] ) f[l][r]=!(f[l+1][r]\&f[l][r-1]) f[l][r]=!(f[l+1][r]&f[l][r1])。把 l , r l,r l,r看做x轴y轴,对每个 l l l求出最大的 r r r使得 s [ l , r ] s[l,r] s[l,r] t t t的子串,并在 ( l , r ) (l,r) (l,r)处标记为必败态,那么相当于从 ( 1 , r ) (1,r) (1,r)走到边界:
在这里插入图片描述
求最大的 r r r就对 t t t建SAM,然后让 s s s在上面跑,如果跑不动了当前长度就是最大的 r r r,当 l l l增加时就让指针沿fail回退,如果回退后的 l e n len len等于当前长度就可以继续往下匹配,否则就是上一回的 r r r

平等博弈,SG

感觉SG函数应该起源于Nim游戏。

  • 两个人取石子,每次可以取 [ 1 , k ] [1,k] [1,k]个,不能取的输,求先手胜负。
    S G [ i ] = i % ( k + 1 ) SG[i]=i\%(k+1) SG[i]=i%(k+1)

  • 两个人取石子,每次可以取 [ l , r ] [l,r] [l,r]个,不能取的输,求先手胜负。
    S G [ i ] = i % ( l + r ) l SG[i]=\frac {i\%(l+r)}l SG[i]=li%(l+r)

  • 一个1*n的木条,每次可以取连续的两个格子, S G [ n ] SG[n] SG[n] n = 1 n=1 n=1开始依次为:在这里插入图片描述
    只需要打完表后放入记事本中,打开自动换行,再慢慢拖动边框,就可以发现循环节了(奇怪的知识增加了! ,注意这个循坏是在第三行后才一模一样的。

例1:SPOJ11414 COT3 【博弈论 + Trie树合并】

在这里插入图片描述
f [ u ] [ v ] f[u][v] f[u][v]表示 u u u的子树中翻转 u → v u\to v uv这条路径后的SG值,那么 f [ f a ] [ v ] = f [ u ] [ v ] ⊕ ( f a 的 其 它 子 树 的 S G 值 ) f[fa][v]=f[u][v]\oplus(fa的其它子树的SG值) f[fa][v]=f[u][v](faSG)。需要维护一个数据结构,支持整体异或上 k k k,合并,求mex。Trie树比较合适。
题解&Code

例2:Codeforces 1091 H【bitset优化求SG】

在这里插入图片描述
题解
问题转化之后变为求 S G [ x ] = m e x d ( S G [ x − d ] ) SG[x]=mex_{d}(SG[x-d]) SG[x]=mexd(SG[xd])。直接做是 O ( n 2 ) O(n^2) O(n2)的。
暴力打表之后发现SG值普遍很小,<=100。
b i t s e t   f [ i ] bitset~f[i] bitset f[i]表示有哪些位置的后继中存在 S G = i SG=i SG=i
那么更新就是 f [ S G [ x ] ] ∣ = D < < x f[SG[x]]|=D<<x f[SG[x]]=D<<x。求 S G [ x ] SG[x] SG[x]就枚举 i i i然后看 f [ i ] [ x ] f[i][x] f[i][x]是否为0即可。
复杂度 O ( n ∗ S G + n 2 w ) O(n*SG+\frac {n^2}w) O(nSG+wn2)

N阶Nim游戏

下面这一段是摘自clover_hxy:Nim 游戏及其变形

n堆石子,每次从不超过k堆中取任意多个石子,最后不能取的人失败。
这是一个nim游戏的变形,也是有结论的。

结论为:把n堆石子的石子数用二进制表示,统计每个二进制位上1的个数,若每一位上1的个数mod(k+1)全部为0,则必败,否则必胜。

证明如下:
1.全为0的局面一定是必败态。
2.任何一个P状态,经过一次操作以后必然会到达N状态:在某一次移动中,至少有一堆被改变,也就是说至少有一个二进制位被改变。由于最多只能改变k堆石子,所以对于任何一个二进制位,1的个数至多改变k。而由于原先的总数为k+1的整数倍,所以改变之后必然不可能是k+1的整数倍。故在P状态下一次操作的结果必然是N状态。
3.任何N状态,总有一种操作使其变化成P状态。从高位到低位考虑所有的二进制位。假设用了某种方法,改变了m堆,使i为之前的所有位都回归到k+1的整数倍。现在要证明总有一种方法让第i位也恢复到k+1的整数倍。

有一个比较显然的性质,对于那些已经改变的m堆,当前位可以自由选择1或0.
设除去已经更改的m堆,剩下堆i位上1的总和为sum
分类讨论:
(1)sum<=k-m,此时可以将这些堆上的1全部拿掉,然后让那m堆得i位全部置成0.
(2)sum>k-m 此时我们在之前改变的m堆中选择k+1-sum堆,将他们的第i位设置成1。剩下的设置成0.由于k+1-sum<k+1-(k-m)<m+1,也就是说k+1-sum<=m,故这是可以达到的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值