再次做了下这个题目,学习了下sg函数
在sg函数中 最终状态的sg值为0 其余状态的sg值为其子状态中未出现过的第一个自然数值
在多组游戏同时进行的情况下,整个组合博弈的sg值为不同组sg值的异或
const int maxn = 2e6 + 4;
const int maxm = 2e1 + 4;
const double pi = acos(-1.0);
int sg[maxn];
int getsg(int num){
if (sg[num] != -1) return sg[num];
bool vis[maxm];
memset(vis, false, sizeof vis);
for (int i = 0, j; i < 20; ++i)
if (num >> i & 1){
for (j = i + 1; j < 20; ++j)
if (!(num >> j & 1)) break;
if (j == 20) continue;
int temp = num - (1 << i) + (1 << j);
vis[getsg(temp)] = true;
}
for (int i = 0; i < maxm; ++i) if (!vis[i]) return sg[num] = i;
}
int m;
int main(){
//必须编译过才能交
int ik, i, j, k, kase;
memset(sg, -1, sizeof sg);
scanf("%d", &kase);
while(kase--){
scanf("%d", &m);
int ans = 0;
for (i = 0; i < m; ++i){
int n, num, ret = 0;
scanf("%d", &n);
while(n--){
scanf("%d", &num);
num--;
ret += 1 << num;
}
ans ^= getsg(ret);
}
puts(ans ? "YES" : "NO");
}
return 0;
}