nyoj 947 Max Xor(字典树)

来源:互联网 发布:暖男的同义网络词 编辑:程序博客网 时间:2024/05/22 14:33

Max Xor

时间限制:3000 ms  |  内存限制:65535 KB
难度:4
描述
给一个长度为 n 的数列 {an} ,找出 max {ai ^ aj}。
输入
多组测试数据。
第 1 行 1 个数 n。(1<=n<=10^5)
接下来的 1 行有 n 个数 ai。(0<=ai<=10^12)
输出
1 行有 1 个数,max {ai ^ aj}。
样例输入
30 1 2
样例输出
3


解题思路:这道题很巧妙,首先把数字变成01串,这个很容易想到,但关键是如何处理这些01串,使得其xor最大。这里采用了字典树,将所有01串都放在字典树上,然后通过字典树的匹配去寻找最大的xor值。

#include<iostream>#include<cstdio>#include<cstring>#include<cstdlib>using namespace std;typedef long long LL;const int maxn = 100005;struct Node{Node *next[2];};int n,c[55];LL a[maxn];Node *root;void process(LL s){int num = 50;memset(c,0,sizeof(c));while(s){c[num--] = s % 2;s /= 2;}}void insert(LL s){process(s);Node *p = root;for(int i = 0; i <= 50; i++){if(p->next[c[i]] == NULL){p->next[c[i]] = (Node *)malloc(sizeof(Node));p->next[c[i]]->next[0] = NULL;p->next[c[i]]->next[1] = NULL;}p = p->next[c[i]];}}LL find(LL s){process(s);Node *p = root;LL sum = 0;for(int i = 0; i <= 50; i++){if(p->next[!c[i]] == NULL){sum = sum * 2;p = p->next[c[i]];}else {sum = sum * 2 + 1;p = p->next[!c[i]];}}return sum;}int main(){while(scanf("%d",&n)!=EOF){for(int i = 1; i <= n; i++)scanf("%lld",&a[i]);root = (Node *)malloc(sizeof(Node));root->next[0] = root->next[1] = NULL;for(int i = 1; i <= n; i++)insert(a[i]);LL ans = 0;for(int i = 1; i <= n; i++)ans = max(ans,find(a[i]));printf("%lld\n",ans);}return 0;}


0 0
原创粉丝点击