当前位置: 代码迷 >> 综合 >> CH 1602 The XOR Largest Pair 字典树+异或
  详细解决方案

CH 1602 The XOR Largest Pair 字典树+异或

热度:84   发布时间:2024-01-15 07:18:47.0

题目地址:http://contest-hunter.org:83/contest/0x10%E3%80%8C%E5%9F%BA%E6%9C%AC%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84%E3%80%8D%E4%BE%8B%E9%A2%98/1602%20The%20XOR%20Largest%20Pair

描述

在给定的N个整数A1,A2……AN中选出两个进行xor运算,得到的结果最大是多少?

输入格式

第一行一个整数N,第二行N个整数A1~AN。

输出格式

一个整数表示答案。

样例输入

3
1 2 3

样例输出

3

数据范围与约定

  • 对于100%的数据: N<=10^5, 0<=Ai<2^31

算法分析:

题目要求寻找2个数异或的最大值,我们把每个整数看做长度为32的二进制的01串(数值较小的时候前面补0),并把A1---Ai-1(注意这里i是动态的,没一次Ai放进去之前都要查询一遍)对应的32位二进制串插入一颗Trie树(其中最低二进制位位叶子节点)。然后,关键是字典树查询代码,我们可以由异或的性质的知道,不同为1,相同为0,所以我们在查询的时候要贪心的寻找不同的,如果实在不通再按照原路线走。

代码有二进制对应的作用


代码实现:

#include <iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
const int maxnode=1000000+100;
const int sigma_size=35;
struct Trie
{int ch[maxnode][sigma_size];int sz;void init(){sz=1;memset(ch[0],0,sizeof(ch[0]));}void insert(int x){int u=0;for(int i=31;i>=0;i--){int id=(x>>i)&1;//取出x二进制第i位if(ch[u][id]==0){ch[u][id]=sz;memset(ch[sz],0,sizeof(ch[sz]));sz++;}u=ch[u][id];}}int find(int x){int ans=0,u=0;for(int i=31;i>=0;i--){int id=(x>>i)&1;int y=id^1;    //找与id不同的if(ch[u][y]==0){u=ch[u][id];ans<<=1;      //相同为0,ans=ans*2}else{u=ch[u][y];ans=ans<<1|1;  //不同为1,ans=ans*2+1	}}return ans;}
};
Trie trie;
int main()
{trie.init();int maxx=0;int n;scanf("%d",&n);for(int i=1;i<=n;i++){int x;scanf("%d",&x);maxx=max(maxx,trie.find(x));trie.insert(x);}cout<<maxx<<endl;return 0;
}