拆分
给定 $n$ 堆石子。
有两名玩家轮流操作,每次操作可以取走一堆,并放入两堆规模更小的石子(可以为0),无法进行合法操作即为失败。
同样利用 $SG$ 函数来解答。
对于一堆石子 $a_i$,总共可以拆分出来 $a_i^2$的种局面,假设都分为了 $x, y$ ,那么:
$$
SG(a_i) = \bigoplus_{0\leq x \leq y < a_i} SG(x) \oplus SG(y)
$$
最后将所有石子堆的 $SG$ 值异或即可。
代码
int sg(int x){
if ( ~ f[x]) return f[x]; //记忆化搜索
bool vis[N] = {0};
for (int i = 0; i < x; i ++ )
for (int j = 0; j <= i; j ++ )
vis[sg(i) ^ sg(j)] = 1;
for (int i = 0; ; i ++ )
if (!vis[i]) return f[x] = i;
}