由于最近在做博弈的课件,做到nim游戏的时候突然就在想如果出一道交互题,用程序跟电脑玩游戏,保证开始时是必胜的,我们应该怎样操作?
基本目标
根据定义,设当前xor和为v,我们就是要找出一个石子堆的石子数 ai 使得ai>v xor ai(因为我们必须只能减少石子堆的石子数)然后将这堆石子的个数改为v xor ai(此时xor和就变成0了,对方就变成必败状态),直接暴力的话,我们每次就需要O(n)的时间
由SG定理的证明想到的结论
在证明SG定理中对于任意a∈N且a
为什么?
因为k位以上的我们不动它们,那么这些位就没有影响,然后由于k位变成了0,那么0~k-1位,无论我们怎么设置都是小于原来的数的,所以一定可以找到一个刚好使xor和变成0的数,当然了,任意一个k位上是1的是可以的。
具体做法
然后就变得很简单了,具体的做法就是,对于每一个二进制位开一个set,set里存放着这个二进制值为1的数的位置。
然后查询时就是找到v的二进制最高位k,我们在k的set里面随便找到一个数,在其他位的set里面删掉这个数,然后就计算要替换成什么数,接着就将这个数放进去应该放进去的set里面,时间复杂度
O(log2n)