AcWing 143. 最大异或对
思路
按照每一位是 0 是 1 建立字典树
由于异或时不同为 1 ,查找时按照反方向查找
注意
- 如果反方向不存在记得回到正方向
- 从高位到低位建树,相当于贪心策略,1 在高位更优
//看题解前的丑代码...
#include <iostream>
#include <cstdio>
const int N = 100005;
int tot = 1;
int trie[N][2], end[N<<5], a[N];
int max(int a, int b)
{
return a > b ? a : b;
}
void insert(int x)
{
int p = 1;
for(int i = 31; i >= 0; i--)
{
int next = (a[x] & (1 << i)) >> i;
if(!trie[p][next]) trie[p][next] = ++tot;
p = trie[p][next];
}
end[p] = x;
}
int search(int x)
{
int p = 1;
for(int i = 31; i >= 0; i--)
{
int next = (x & (1 << i)) >> i ^ 1;
if(!trie[p][next]) next = next ^ 1;
p = trie[p][next];
}
return a[end[p]];
}
int main(){
int n;
scanf("%d", &n);
int ans = 0;
for(int i = 0; i < n; ++i)
{
scanf("%d", &a[i]);
//printf("%d %d %d\n", search(a[i]), a[i], search(a[i]) ^ a[i]);
ans = max(ans, search(a[i]) ^ a[i]);
insert(i);
}
printf("%d\n", ans);
return 0;
}
//借鉴后...
#include <iostream>
#include <cstdio>
const int N = 100005;
int tot = 1;
int trie[N<<5][2], a[N];
int max(int a, int b)
{
return a > b ? a : b;
}
void insert(int x)
{
int p = 1;
for(int i = 30; i >= 0; i--)
{
int next = (a[x] >> i) & 1;
if(!trie[p][next]) trie[p][next] = ++tot;
p = trie[p][next];
}
}
int search(int x)
{
int p = 1;
int ans = 0;
for(int i = 30; i >= 0; i--)
{
int next = (x >> i) & 1;
if(trie[p][next ^ 1])
{
p = trie[p][next ^ 1];
ans |= 1 << i;
}
else
p = trie[p][next];
}
return ans;
}
int main(){
int n;
scanf("%d", &n);
int ans = 0;
for(int i = 0; i < n; ++i)
{
scanf("%d", &a[i]);
//printf("%d %d %d\n", search(a[i]), a[i], search(a[i]) ^ a[i]);
ans = max(ans, search(a[i]));
insert(i);
}
printf("%d\n", ans);
return 0;
}