首先我们可以通过数据范围提示(x < 2^20)这么写范围一般都是要拆为二进制解决问题(((
将所有数拆为二进制,因为亦或运算每一位单独运算,不会影响其他位,所以要使自己的数最大就要使自己高位比对方的大;
所以我们从最高位考虑,判断这一位谁能比对方大,从高位开始对于每一位求出该位二进制下1的数目cnt;
1.若cnt为偶数,则该位所有数亦或的结果为0,假设双方拿完所有数后当前位为a和b,则a ^ b = 0,当且仅当相同的数亦或为0,则a == b;所有当前无论怎么选双方值都相同,所以当cnt为偶数时continue;
2.若当cnt为奇数时,可以发现最后一个1谁拿谁获胜,因为去掉最后一个1,由上可知双方当前位值相同,若双方为1则放在对方,若双方为0放在自己,则必胜,谁能拿到最后的1我们需要考虑0的个数;
2.1若0的个数为偶数(总数为奇数),a先手拿1,然后之后无论b拿什么a跟着拿,由于a拿走第一个1后,1的数目和0的数目都为偶数,所以可以确保a一定可以拿到最后的1,即先手必胜!
2.2若0的个数位奇数(总数为偶数),a先手拿1则b拿0,a先手拿0则b拿1,第一轮结束后,留给先手的状态为1的个数和0的个数都为偶数,由上可知该状态为必败态(b只需模仿a即可保证自己拿到最后的1),后手必胜!
2.3特别的,需要特判cnt为1的情况先手必胜!
3.若每一位的1个数都为偶数则平手!
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<ctime>
#include<cmath>
#include<string>
#include<cstring>
#include<bitset>
#include<vector>
#include<queue>
#include<stack>
#include<set>
#include<map>
#include<iomanip>
#include<algorithm>
#define IOS ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
#define endl "\n"
#define int long long
#define PI acos(-1)
//CLOCKS_PER_SEC clock()函数每秒执行次数
using namespace std;
const int INF = 0x3f3f3f3f;
const int N = 2e6+5,M = N * 2;
int mod = 1e9 +7;
int n,m,k,S,T;
int a[N];
void solve(){
cin >> n;
for(int i = 1 ; i <= n ; ++i) cin >> a[i];
for(int i = 20 ; i >= 0 ; --i){
int cnt = 0;
for(int j = 1 ; j <= n ; ++j) if(a[j] >> i & 1) cnt++;
if(cnt % 2 == 0) continue;
if(n % 2 == 1 || cnt == 1){
cout << 1 << endl;
return;
}
else{
cout << -1 << endl;
return;
}
}
cout << 0 << endl;
return;
}
signed main(){
IOS;
int tt;
cin >> tt;
while(tt--)
solve();
return 0;
}
/*
*
* ┏┓ ┏┓+ +
* ┏┛┻━━━┛┻┓ + +
* ┃ ┃
* ┃ ━ ┃ ++ + + +
* ████━████+
* ◥██◤ ◥██◤ +
* ┃ ┻ ┃
* ┃ ┃ + +
* ┗━┓ ┏━┛
* ┃ ┃ + + + +Code is far away from
* ┃ ┃ + bug with the animal protecting
* ┃ ┗━━━┓ 神兽保佑,代码无bug
* ┃ ┣┓
* ┃ ┏┛
* ┗┓┓┏━┳┓┏┛ + + + +
* ┃┫┫ ┃┫┫
* ┗┻┛ ┗┻┛+ + + +
*/
流批