思路:双指针找到每个1的下一个0,然后暴力计算
#include<bits/stdc++.h>
using namespace std;
const int N=21,M=1<<N;
int sg[M];
int vis[M];
int T,n;
int SG(int s)
{
if(~sg[s]) return sg[s];
for(int i=19,j=i-1;i>=0;i--)
{
j=min(j,i-1);
while(j>=0&&((s>>j)&1)) j--;
if(!((s>>i)&1)) continue;
if(j>=0)
{
int t=s^(1<<i)^(1<<j);
vis[SG(t)]=s;
}
}
int res=0;
while(vis[res]==s) res++;
return sg[s]=res;
}
signed main()
{
memset(vis,-1,sizeof vis);
cin>>T;
memset(sg,-1,sizeof sg);
while(T--)
{
cin>>n;
int res=0;
for(int i=1,m,x;i<=n;i++)
{
int s=0;
cin>>m;
while(m--)
{
cin>>x;
x=20-x;
s|=(1<<x);
}
res^=SG(s);
}
if(res) cout<<"YES\n";
else cout<<"NO\n";
}
return 0;
}