用01字典树来求解一组数据异或值的最大值或者最小值:
对于01字典树来说,是将数的二进制形式储存到字典树中,当你去搜索x与字典树中某值异或最大时,根据以下思路:
对于异或而言,1^1=0,0^0=0,1^0=1,想要求异或的最大值,就要求在二进制下与当前x的第i位不同的数。
比如x的二进制为101110,那么想得到与x异或结果最大,应该让x异或p:010001,即结果为111111,这个值就是x可能异或最大的值。
在01字典树中储存的是一组p的二进制形式,当你有x想要与这组p异或找最大值时,可以认为是一种贪心算法,即从x的最高位开始放入字典树查询,如果有与最高位不同的就放入从这个位置开始匹配,直到匹配到结束。
代码实现:
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
using namespace std;
const int M=100005;
int Trie[M][2],tot,sym[M];
void create_trie(int x)
{
int now=0;
for(int i=32;i>=0;i--)
{
int tmp = (x>>i)&1;
if(!Trie[now][tmp])
{
Trie[now][tmp]=++tot;
}
now=Trie[now][tmp];
}
sym[now]=x;
}
int query(int x)
{
int now=0;
for(int i=32;i>=0;i--)
{
int tmp=(x>>i)&1;
if(Trie[now][tmp^1]) now=Trie[now][tmp^1];
else
now=Trie[now][tmp];
}
return v[now];
}
求最小值时,就将query函数的判断部分交换一下就ok。
对于部分题目,应再加一个sum[now]的属性,对于用过的就--,不再使用。