BZOJ 4269 再见Xor

2017.07.27

题目大意

给定N个数,你可以在这些数中任意选一些数出来,每个数可以选任意多次,试求出你能选出的数的异或和的最大值和严格次大值。


线性代数题= =

首先我们需要对这些东西进行异或处理。题目说可以使用多次,我们为了保证简便希望只用一次,所以使用高斯消元保证每一个数都不是由别的数演化而来的确保唯一性,之后直接进行异或操作,全异或就是结果,把最小的数T出去不不进行异或就是次大值了。

#include <cstdio>
#include <algorithm>
using namespace std;
int n,a[100010],ans,now=0;
void Gause_Elimination()
{
	for(int i=1<<30;i;i>>=1)
	{
		int choice;
		for(choice=now+1;choice<=n;++choice)
		{
			if(a[choice]&i) break;
		}
		if(choice==n+1) continue;
		swap(a[++now],a[choice]);
		for(int j=1;j<=n;++j)
			if(j!=now&&(a[j]&i)) a[j]^=a[now];
	}
	//for(int i=1;i<=n;++i) printf("%d ",a[i]);
	//printf("\n");
	for(int i=1;i<=n;++i) ans^=a[i];
	printf("%d ",ans);
	while(!a[n]) n--;
	ans^=a[n];
	printf("%d",ans);
}
int main()
{
	scanf("%d",&n);
	for(int i=1;i<=n;++i) scanf("%d",a+i);
	Gause_Elimination();
	return 0;
}