HDU-3949 XOR

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/C_13579/article/details/82694067

地址:http://acm.hdu.edu.cn/showproblem.php?pid=3949

思路:先求出a[]的线性基f[],然后将线性基的每一位进行消除使其只有本身的那一位,在将f[i]中非0的全部移动f[1,m]中,m为非0的个数,这样对于第K个数,就是将K转为二进制中为1的f[]异或起来即可。另外还要处理有0的情况,这时需要将K-=1

Code :

#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
typedef long long LL;

int n,m,Q,T;
int pp;
LL f[65];
void Insert(LL x);
void Build();
LL Query(LL k);

int main()
{
	scanf("%d",&T);
	for(int t=1;t<=T;++t)
	{
		memset(f,0,sizeof(f));
		pp=m=0;
		scanf("%d",&n);
		LL x;
		for(int i=0;i<n;++i)
		{
			scanf("%lld",&x);
			Insert(x);
		}
		Build();
		printf("Case #%d:\n",t);
		scanf("%d",&Q);
		while(Q--){
			scanf("%lld",&x);
			x-=pp;
			if(x>=((LL)1<<m))	printf("-1\n");
			else	printf("%lld\n",Query(x));
		}
	}
	
	return 0;
}

void Insert(LL x)
{
	for(int i=63;i>=0;--i)
		if(x>>i){
			if(!f[i]){
				f[i]=x;	break;
			}
			x^=f[i];
		}
	if(!x)	pp=1;
}

void Build()
{
	for(int i=0;i<=63;++i)
		for(int j=i+1;j<=63;++j)
			if((f[j]>>i)&1)	f[j]^=f[i];
	for(int i=0;i<=63;++i)
		if(f[i])	f[m++]=f[i];
}

LL Query(LL k)
{
	int i=0;
	LL res=0;
	while(k){
		if(k&1)	res=res^f[i];
		k>>=1;	++i;
	}
	return res;
}

猜你喜欢

转载自blog.csdn.net/C_13579/article/details/82694067
xor