https://gmoj.net/senior/#main/show/6823
这算是我SG函数的入门题吧…… 不妨先考虑每一堆石子中的情况,设 f i f_i fi表示操作前堆中有 i 个石子时,当前操作的玩家是否是取完这堆石子的那个玩家(记为0/1,0不是1是),或者他可以自由选择0或1状态(记为2)。 这样显然 f b = 0 f_b=0 fb=0, f i = m e x { f i ⋅ k , i ≤ ⌊ b k ⌋ f i + 1 , 1 ≤ i < b f_i=mex\begin{cases} f_{i\cdot k}&,i\leq \left\lfloor\frac{b}{k}\right\rfloor\\ f_{i+1} \end{cases},1\leq i<b fi=mex{fi⋅kfi+1,i≤⌊kb⌋,1≤i<b 通过打表找规律,可以发现 [ ⌊ b k ⌋ + 1 , b ] , [ ⌊ ⌊ b k ⌋ k ⌋ + 1 , ⌊ b k ⌋ ] , ⋯ \left[\left\lfloor\cfrac{b}{k}\right\rfloor+1,b\right],\left[\left\lfloor\cfrac{\left\lfloor\frac{b}{k}\right\rfloor}{k}\right\rfloor+1,\left\lfloor\cfrac{b}{k}\right\rfloor\right],\cdots [⌊kb⌋+1,b],[⌊k⌊kb⌋⌋+1,⌊kb⌋],⋯这些区间中除前两个 f 外,其它 f 都是循环的,且循环节长度为2(即0 2 0 2 0 2 0 2……这样的)。 因此维护每个区间的前4位就好了,计算单个堆的时间复杂度为 O ( log k b ) O(\log_kb) O(logkb),这个块的sg函数值为 f a f_a fa。 接着如果 S G ( 1 ) ⨁ S G ( 2 ) ⨁ ⋯ ⨁ S G ( n ) = 0 SG(1)\bigoplus SG(2)\bigoplus\cdots\bigoplus SG(n)=0 SG(1)⨁SG(2)⨁⋯⨁SG(n)=0,那么Bob胜;否则Alice胜(SG定理)。 其实也可以换一种理解:
sg值为0的块不改变先后手,sg为1的块强制改变先后手,sg为2的块则是可以自由选择是否改变先后手。最后后手必胜。 可以把两人的操作视为两部分:第一部分是操作sg为0/1的块,第二部分是操作sg为2的块,前者的结果是固定的。现在的问题就变成了一开始有一个人必败,另一个人必胜,两个人每次可以改变或不改变胜利者,问最后谁必胜。 这其实就是谁的sg为2的块多,谁就赢;一样多就不改变胜利情况。由于Alice先选,她的sg为2的块绝对不会比Bob少,因此当sg为2的块的个数为奇数时,Alice必胜;为偶数时,等于忽略sg为2的块的子问题。