HDU - 4825 Xor Sum(字典树)

题目链接:点击查看

题目大意:给出n个数组成的数组,再给出m个询问,每次询问给出一个x,要求从数组中选出一个k,使得k^x的值最大

题目分析:字典树求异或值最大的模板题,对于n个数直接insert到字典树中,然后对于每个查询直接贪心从树上找就是答案了,不太一样的地方是这个题目要求输出的不是答案而是原数,那么我们对于每个节点多维护一下其原来的数,也就是映射一下,最后查询的时候直接返回这个映射就是答案了

或者还有一种办法,因为异或运算的特殊性,k^x=ans,同样可以有ans^x=k,所以我们只需要对于求出来的答案再对x异或一下就是我们所要求得k了,两者等价

代码:

#include<iostream>
#include<cstdio> 
#include<string>
#include<ctime>
#include<cstring>
#include<algorithm>
#include<stack>
#include<queue>
#include<map>
#include<set>
#include<sstream>
#include<unordered_map>
using namespace std;

typedef long long LL;

const int inf=0x3f3f3f3f;

const int N=1e5+100;

int trie[N*35][2],cnt;

LL val[N*35];

int newnode()
{
	cnt++;
	trie[cnt][0]=trie[cnt][1]=0;
	return cnt;
}

void insert(LL num)
{
	int pos=0;
	for(int i=32;i>=0;i--)
	{
		int to=(num>>i)&1;
		if(!trie[pos][to])
			trie[pos][to]=newnode();
		pos=trie[pos][to];
	}
	val[pos]=num;
}

LL search(LL num)
{
	int pos=0;
	for(int i=32;i>=0;i--)
	{
		int to=(num>>i)&1;
		if(trie[pos][!to])
			pos=trie[pos][!to];
		else
			pos=trie[pos][to];
	}
	return val[pos];
}

void init()
{
	trie[0][0]=trie[0][1]=0;
	cnt=0;
}

int main()
{
//	freopen("input.txt","r",stdin);
//	ios::sync_with_stdio(false);
	int w;
	cin>>w;
	int kase=0;
	while(w--)
	{
		init();
		int n,m;
		scanf("%d%d",&n,&m);
		while(n--)
		{
			LL num;
			scanf("%lld",&num);
			insert(num);
		}
		printf("Case #%d:\n",++kase);
		while(m--)
		{
			LL x;
			scanf("%lld",&x);
			printf("%lld\n",search(x));
		}
	}
	
	
	
	
	
	
	
	
	
	
	
	return 0;
}
发布了558 篇原创文章 · 获赞 16 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/qq_45458915/article/details/104012967