题目链接: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;
}
本文介绍了一种利用字典树解决最大异或值问题的方法。通过将每个数字转化为31位二进制数并插入字典树中,然后针对每个数字找到与其异或值最大的配对数字。主要步骤包括初始化字典树、插入数字和查询最大异或值。
658

被折叠的 条评论
为什么被折叠?



