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}。 样例输入
-
3 0 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; }
-
多组测试数据。