因为每个豆子都是互相独立的,所以各看成一个子博弈
他们之间的状态只和位置有关,因为每次操作都会多出一个豆子,相当于多一个子博弈
那就是 $multi-SG$ 模型了,数据很小,考虑直接求出每个状态的 $SG$ 值
根据 $multi-SG$ 的理论,设 $SG[i]$ 表示第 $i$ 个位置的 $SG$,那么有 $SG[i]=mex(SG[j]\ xor\ SG[k]),i<j<=k<=n$
然后枚举第一步怎么走,看看走完后总的 $SG$ 是不是 $0$ 就知道后手是不是必败了
当然如果把位置倒过来求 $SG$,就只要预处理一次 $SG$,因为那样 $SG$ 就与 $n$ 无关了
#include<iostream> #include<cstdio> #include<algorithm> #include<cstring> #include<cmath> using namespace std; typedef long long ll; inline int read() { int x=0,f=1; char ch=getchar(); while(ch<'0'||ch>'9') { if(ch=='-') f=-1; ch=getchar(); } while(ch>='0'&&ch<='9') { x=(x<<1)+(x<<3)+(ch^48); ch=getchar(); } return x*f; } const int N=27,M=1e6+7; int n,a[N],SG[N],vis[233]; void pre() { memset(vis,-1,sizeof(vis)); memset(SG,0,sizeof(SG)); for(int i=n-1;i>=0;i--) { for(int j=i+1;j<=n;j++) for(int k=j;k<=n;k++) vis[SG[j]^SG[k]]=i; while(vis[SG[i]]==i) SG[i]++; } } inline void solve(int ans) { int cnt=0,a=0,b=0,c=0; for(int i=1;i<n;i++) for(int j=i+1;j<=n;j++) for(int k=j;k<=n;k++) if((ans^SG[i]^SG[j]^SG[k])==0) if(!(cnt++)) a=i,b=j,c=k; printf("%d %d %d\n%d\n",a-1,b-1,c-1,cnt); } int main() { int T=read(); while(T--) { n=read(); pre(); int ans=0; for(int i=1;i<=n;i++) a[i]=read(),ans^=(a[i]&1 ? SG[i] : 0); if(!ans) printf("-1 -1 -1\n0\n"); else solve(ans); } return 0; }