组合博弈 就是转化成取石子模型,然后把se函数通过mex运算求出来,几个独立的游戏的se[i]值抑或起来是0后手赢,非零前手赢
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
using namespace std;
int sg[2200000];
int ve[1000],l;
void getSg()
{
int maxi = (1<<20);
for(int pre = 0; pre < maxi; pre++)
{
int zeroPos = -1;
l = 0;
ve[l++] = -1;
ve[l++] = 10000000;
for(int i = 0;i <= 19;i++)
{
if((1<<i)>pre)break;
if(((1<<i)&pre))
{
if(zeroPos>=0)
{
int tmp = pre;
tmp ^= (1<<i);
tmp ^= (1<<zeroPos);
ve[l++] = sg[tmp];
}
}
else zeroPos = i;
}
sort(ve,ve+l);
for(int i = 1; i < l; i++)
{
if(ve[i]>ve[i-1]+1)
{
sg[pre] = ve[i-1]+1;
break;
}
}
}
}
int main()
{
getSg();
int t;
scanf("%d", &t);
while(t--)
{
int n, ans = 0;
scanf("%d", &n);
while(n--)
{
int pre = 0;
int m;
scanf("%d", &m);
while(m--)
{
int tmp;
scanf("%d", &tmp);
pre |= (1<<(20-tmp));
}
ans ^= sg[pre];
}
if(ans)printf("YES\n");
else printf("NO\n");
}
return 0;
}