01字典树+贪心

用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]的属性,对于用过的就--,不再使用。

猜你喜欢

转载自blog.csdn.net/Black__wing/article/details/81315397