P8743 [蓝桥杯 2021 省 A] 异或数列 题解

发布时间 2023-12-20 09:04:29作者: jr_inf

题意补充:初始 \(a,b\) 均为 \(0\)

位越高对 \(a,b\) 的贡献越大,所以从高位往低位考虑。给几组样例以便分析:

1 0 0 0 0

1 1 0 0 0

1 1 1 0 0

1 1 1 0

答案分别是 \(1,0,-1,1\)

设当前位有 \(x\)\(1\),有 \(y\)\(2\)

  • 如果 \(x=1\),Alice 必胜。
  • 如果 \(2|x\),当前位无法判断。
  • 如果 \(x \neq 1\)\(2|x+1\),如果 \(2|y\),Alice 必胜,否则 Bob 必胜。

对于第二种情况,无论如何选择,Alice 和 Bob 选择的 \(1\) 的个数的奇偶性相同;对于第三种情况,双方同时选 \(0\) 的情况不会影响答案,可以将 \(y\) 视为 \(y \% 2\)。选了奇数个 \(1\) 的人才能得到贡献,所以如果 \(y=0\),Alice 必败,否则 ta 可以通过选 \(0\) 来夺回优势。

按照上述思路从高位往低位分析即可。

code:

#include<iostream>
#include<cstdio>
using namespace std;
const int N=2e5+10;
int t,n,c[N],maxn;
int get(int x)
{
	int cnt=0;
	while(x)x/=2,cnt++;
	return cnt;
}
int work()
{
	for(int i=get(maxn);i>=0;i--)
	{
		int cnt=0;//文中 x
		for(int j=1;j<=n;j++)cnt+=bool((c[j]>>i)%2);
		if(cnt==1)return 1;
		else if(cnt%2)return(n-cnt)%2?-1:1;
	}
	return 0;
}
signed main()
{
	scanf("%d",&t);
	while(t--)
	{
		maxn=0;
		scanf("%d",&n);
		for(int i=1;i<=n;i++)scanf("%d",&c[i]),maxn=max(maxn,c[i]);
		printf("%d\n",work());
	}
}