有一个2个人玩的游戏,有n个圆环,每次的操作是选择一个大小不小于2的圆环,把它分成x,N-x(1<=x < N)2个子圆环。
换句话说,就是给你n堆石子,然后每次选择大小不小于2的分成2个小堆,且每堆大小大于0,不能操作的输。
题目问的是,给出n堆,n个询问,选择前i堆作为游戏开始,先手赢还是后手赢。
先用sg函数,打表计算下规律,打表的规律是奇数是0,偶数是1
然后直接异或就好了
#include<bits/stdc++.h>
using namespace std;
#define cl(a,b) memset(a,b,sizeof(a))
#define LL long long
#define pb push_back
#define gcd __gcd
#define For(i,j,k) for(int i=(j);i<k;i++)
#define lowbit(i) (i&(-i))
#define _(x) printf("%d\n",x)
const int maxn = 1e6+10;
const int inf = 1 << 28;
set<int> s;
int sg[maxn];
int grundy(int k){
s.clear();
sg[1]=0;
// s.insert(sg[1]);
for(int i=1;i<k;i++){
s.insert(sg[i]^(sg[k-i]));
}
int ans = 0;
while(s.count(ans))ans++;
sg[k]=ans;
return ans;
}
int sg_(int x){
if(x%2==0)return 1;
else return 0;
}
int main(){
/* for(int i=1;i<=25;i++){
printf("%2d ",i);
}
cout<<endl;
for(int i=1;i<=25;i++){
printf("%2d ",grundy(i));
}
cout<<endl;*/
int n;scanf("%d",&n);
LL ans = 0;
for(int i=0;i<n;i++){
LL x;scanf("%lld",&x);
ans^=sg_(x);
// cout<<"ans = "<<ans<<endl;
printf("%s\n",ans?"1":"2");
}
return 0;
}