CSU 1216 异或最大值【字典树】

来源:互联网 发布:sap软件是什么 编辑:程序博客网 时间:2024/05/04 21:36

Description

给定一些数,求这些数中两个数的异或值最大的那个值

Input

第一行为数字个数n,1 <= n <= 10 ^ 5。接下来n行每行一个32位有符号非负整数。

Output

任意两数最大异或值

Sample Input

3379

Sample Output

14


/*    类型:字典树+贪心    分析:建一棵01字典树,树的深度就是整数的值的位数,然后根据异或的性质进行贪心    吐槽:刚开始从低位向高位建树,WA了几次没想出所以然,后面才发现,低位开始建树的贪心策略是错的          因为在查找的过程中从高位的路线转移到低位的路线,最后前期贪心的结果没高位的那么多,心塞*/#include<cstdio>#include<algorithm>#include<cstring>#include<iostream>using namespace std;const int len = 31;typedef struct Trie{    Trie *next[2];}Trie;Trie root;void createTrie(int x){    Trie *p = &root, *q;    for(int i=len;i>=0;i--){        bool id = x&(1<<i);        if(p->next[id] == NULL){            q = (Trie *)malloc(sizeof(root));            for(int j=0;j<2;j++)                q->next[j] = NULL;            p->next[id] = q;            p = p->next[id];        }        else{            p = p->next[id];        }    }}int findTrie(int x){    int val=0;    Trie *p = &root;    for(int i=len;i>=0;i--){        bool id = x&(1<<i);        if(p->next[!id]!=NULL){            val=val|(1<<i);            p = p->next[!id];        }        else p = p->next[id];    }    return val;}void deal(Trie* T){    for(int i=0;i<2;i++)    {        if(T->next[i]!=NULL)            deal(T->next[i]);    }    free(T);}int main(){    //freopen("F:\\input.txt", "r", stdin);    int n;    while(~scanf("%d",&n)){        int x,ans=0;        for(int i=0;i<2;i++)root.next[i] = NULL;        while(n--){            scanf("%d",&x);            createTrie(x);            ans=max(ans,findTrie(x));        }        printf("%d\n",ans);        for(int i=0;i<2;i++){            if(root.next[i]!=NULL)                deal(root.next[i]);        }    }    return 0;}





0 0