[ABC255G] Constrained Nim Solution

更好的阅读体验戳此进入

题面

一般 Nim 游戏基础上增加 m 条限制,限制当石子数为 xi 时不能拿走其中的 yi 个。

Solution

显然博弈论,考虑 SG函数。Nim 游戏标准套路,对于多个石子堆求出每个石子堆石子数 aiSG(ai),若 i=1nSG(ai)=0 则先手必输,反之必胜。关于 SG函数 的详解:SG函数学习笔记

本题的区别即为 m 条限制,考虑如何处理。显然一般 Nim 游戏的 SG 函数有转移 SG(i)=mex{SG(j)j[1,i1]},本题的区别不难想到就是在一般的 SG函数 基础上,在求 mex 的时候需要从中去掉一些值,也就是去掉 SG(xi) 转移中的 SG(xiyi)。严谨点叙述就是 SG(i)=mex{SG(j)j[1,i1](i,j)(xk,xkyk),k[1,m]}。考虑维护,显然值域过大无法硬做。发现每次从中去掉一些值后,mex 的值就会变为最小的被全部删除的元素。然后在这个位置以后,下一条限制以前,每次的 SG(i)=SG(i1)+1。发现整个值的分布实际上就是一些特殊点和很多条斜率为 1 的线段。所以我们对于答案,考虑开个 map 记录转折点,每次查询对应的所在位置然后增加对应数量的 1 即可。

具体实现过程也不难理解,开个 map 里套 basic_string 维护对应 xi 的所有 xiyi,然后遍历,显然升序遍历过程中 xi 以内的 SG 均已确定。然后考虑如何确定当前的 SG(i),不难发现对于没有限制的 SG 值即为其之前的所有 SG 的最大值,也就是前缀最大值 +1。对于有限制的,我们枚举其所有限制,找到最小的一个被删没的值(注意这里比较的时候要 +1,原因是遍历到此时的时候一般情况下会有一个 SG(i)=i),将其设为这个。此为特殊点,然后在其之后的点依然按照一般的斜率为 1 地增长,用前缀最大值更新,记录一下即可。

Code

UPD

update-2022_12_07 初稿