題目鏈接:https://loj.ac/problem/10050
思路:把每一個數字 x 轉化爲31位的二進制數,不夠的前面補0,並插入到字典樹中(最低爲二進制位爲葉節點);
接下來對每一個數字 x 的二進制位進行查找,每一步都儘量找與當前位置相反的數字進行訪問,入如果有相反的數字,根據xor運算這一位就會留下一個 1 ,最後找出最大值就行。
代碼:
#include<bits/stdc++.h>
#define ll long long
#define N 10086111
#define inf 0x3f3f3f3f
using namespace std;
int maxx,tot,ch[N][2];
void Init()
{
memset(ch,0,sizeof(ch));
tot=1;
}
void insertt(int x)
{
int u=1;
for(int i=30;i>=0;i--)
{
int c=x&(1<<i)?1:0;//計算出x每一位上的值
if(!ch[u][c])//如果不存在這條邊
ch[u][c]=++tot;//就新建一個節點與轉移邊
u=ch[u][c];
}
}
int query(int x)//查詢
{
int u=1,ans=0;
for(int i=30;i>=0;i--)
{
int c=x&(1<<i)?1:0;//計算x的每一位上的值
if(ch[u][!c])//如果存在與x這一位數字相反的邊
{
u=ch[u][!c];
ans|=(1<<i);//把這一位上的 1 給添加到ans上
}
else
u=ch[u][c];
}
return ans;
}
int main()
{
Init();
int n;
maxx=0;
scanf("%d",&n);
while(n--)
{
int x;
scanf("%d",&x);
insertt(x);//把x的二進制插入字典樹
maxx=max(maxx,query(x));
}
printf("%d\n",maxx);
return 0;
}