HDU 4285 - Xor Sum(01字典树)

Xor Sum

Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 132768/132768 K (Java/Others)
Total Submission(s): 10153 Accepted Submission(s): 4176

Problem Description

Zeus 和 Prometheus 做了一个游戏,Prometheus 给 Zeus 一个集合,集合中包含了N个正整数,随后 Prometheus 将向 Zeus 发起M次询问,每次询问中包含一个正整数 S ,之后 Zeus 需要在集合当中找出一个正整数 K ,使得 K 与 S 的异或结果最大。Prometheus 为了让 Zeus 看到人类的伟大,随即同意 Zeus 可以向人类求助。你能证明人类的智慧么?

Input

输入包含若干组测试数据,每组测试数据包含若干行。
输入的第一行是一个整数T(T < 10),表示共有T组数据。
每组数据的第一行输入两个正整数N,M(<1=N,M<=100000),接下来一行,包含N个正整数,代表 Zeus 的获得的集合,之后M行,每行一个正整数S,代表 Prometheus 询问的正整数。所有正整数均不超过2^32。

Output

对于每组数据,首先需要输出单独一行”Case #?:”,其中问号处应填入当前的数据组数,组数从1开始计算。
对于每个询问,输出一个正整数K,使得K与S异或值最大。

Sample Input
2
3 2
3 4 5
1
5
4 1
4 6 5 6
3

Sample Output
Case #1:
4
3
Case #2:
4

题目大意:

给出 t 组数据,对于每组数据,输入 n q 表示n 个数和q 个询问,接下来输入n个数,然后再输出q个数,对于每个询问,输出 n 个数中与 该数异或值最大的数。

解题思路:

01字典树模板题,建树以后直接插入查询即可。

Code:

#pragma GCC optimize(2)
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cmath>
#include <vector>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <cstring>
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
const int N = 1e5 + 50;
int tot = 1;
ll val[N * 32], ch[N * 32][2];
void init()
{
	memset(ch, 0, sizeof ch);
	memset(val, 0, sizeof val);
	tot = 1;
}
void insert(ll x)//插入的过程
{
	int u = 0;
	for (int i = 31; i >= 0; i --)
	{
		int v = (x >> i) & 1;//从大到小依次按位&1
		if (!ch[u][v])//如果这个节点没有被访问过则插入新节点
		{
			ch[tot][0] = ch[tot][1] = 0;//下一个节点初始化
			ch[u][v] = tot++;//当前的u v(0或1)指向下一个节点
			val[tot] = 0;//因为没到最底层节点,所以 = 0
		}
		u = ch[u][v];//类似于指针,指向下一个编号
	}
	val[u] = x;
}
ll query(ll x)
{
	int u = 0;
	for (int i = 31; i >= 0; i --)
	{
		int v = (x >> i) & 1;
		if (ch[u][v ^ 1])  u = ch[u][v ^ 1];//每次去找和v不一样的,使异或值最大
		else  u = ch[u][v];
	}
	return val[u];
}
int main()
{
	ios::sync_with_stdio(false);
	int t, k = 1;
	cin >> t;
	while (t--)
	{
		cout << "Case #" << k++ << ':' << endl;
		init();
		int n, q;
		cin >> n >> q;
		for (int i = 1; i <= n; i ++)
		{
			int s;
			cin >> s;
			insert(s);
		}
		while (q--)
		{
			ll s;
			cin >> s;
			cout << query(s) << endl;
		}
	}
	return 0;
}
posted @ 2020-08-03 11:01  Hayasaka  阅读(39)  评论(0编辑  收藏  举报