拆分
给定 n 堆石子。
有两名玩家轮流操作,每次操作可以取走一堆,并放入两堆规模更小的石子(可以为0),无法进行合法操作即为失败。
同样利用 SG 函数来解答。
对于一堆石子 ai,总共可以拆分出来 a2i的种局面,假设都分为了 x,y ,那么:
SG(ai)=⨁0≤x≤y<aiSG(x)⊕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;
}