题目所属分类
异或性质+前缀+字典树
异或的概念:参与运算的两个值,如果两个相应bit位相同,则结果为0,否则为1。
-
0 ^ 0=0,0 ^ 1=1 0异或任何数=任何数
-
1 ^ 0=1,1^1=0 1异或任何数-任何数取反
而二进制表示数的时候 最高位也就是最左位是1 这时候数是最大的 也就是要保持最高位最好都是1
*2相当于左移一位
原题链接
题解
暴力做法
import java.util.Scanner;
public class Main{
static int N = 3100010;
static int[][] son = new int [N][2];
static int idx ;
static int[] a = new int[N];
public static void main(String[] args){
Scanner scan = new Scanner(System.in);
int n = scan.nextInt();
int res = 0 ;
for(int i = 0 ; i < n ; i++){
a[i] = scan.nextInt();
insert(a[i]);
}
//int res = 0;
for (int i = 0; i < n; i ++ ) res =Math.max(res, search(a[i]));
System.out.println(res);
}
static void insert(int x){
int p = 0 ;
for(int i = 30 ; i >= 0 ; i--){
int u = (x >> i)& 1;//取出x当前的第i位数
if(son[p][u] == 0){
son[p][u] = ++idx;
}
p = son[p][u];
}
}
static int search(int x){//这是找出异或值 每次查询异或的那个数结果
int p = 0 , ans = 0 ;
for(int i = 30 ; i >= 0 ; i--){
int u = x >> i & 1;//取出x当前的第i位数
if(son[p][1-u] != 0){
p = son[p][1-u];
// ans = ans * 2 + 1-u ;
ans += (1<<i);// 这个地方与十进制一样 n = n * 10 + x;
}else{
p = son[p][u];
// ans = ans * 2 + u ;
}
}
return ans ;
}
// public static int search(int x){
// int p = 0,res = 0;//从根节点0开始。res进就算异或后的最大值
// for(int i = 30; i>= 0 ; i --){
// int u = x >> i & 1;
// if(son[p][1-u] != 0){ //如果该节点的u是0,则判断一下在这一层有没有跟他相反的0-1,1-0,如果相反对应位置有数
// res += (1 << i);//res就将该二进制位对应异或之后的最优解1每一位顺次加起来。因为是异或相反数就是1,这是最优解
// p = son[p][1-u];//然后往最优解那边前进一层。
// }else{//否则就不是最优解的0匹配1,1匹配0,所以就异或之后的值是0
// //res += (0 << i);因为是0所以可以省略,
// p = son[p][u];//然后让他往不优解那边前进一层。
// }
// }
// return res;//最后返回异或之后的最大值res
// }
}