143. 最大异或对 AcWing
字典树模板题
错误思路:
很容易看出枚举两个数字必定TLE,但这题求最值必须枚举一个数,因此我们可以在枚举第二个数进行优化
正确思路:
在枚举第二个数时,将第一个数的每一位分开贪心求解,将范围内的数全部插入字典数中,查询是否能获得高位尽量与第一个数相反的数
1 #include <iostream> 2 #include <cstdio> 3 using namespace std; 4 const int N = 1e5+10; 5 const int M = 31*N; 6 int idx,son[M][2],a[N]; 7 void insert(int x)//从最高位开始插入 8 {//每个数字都被分解为30位二进制数,因此不需要标记数组 9 int p = 0; 10 for(int i=30;~i;i--){ 11 int t = x>>i&1;//x>>k&1获得x的第k位数字 12 if(!son[p][t]) son[p][t] = ++idx; 13 p = son[p][t];//获得结点下标 14 } 15 } 16 int query(int x) 17 { 18 int p = 0,ans = 0; 19 for(int i=30;~i;i--){ 20 int t = x>>i&1; 21 if(son[p][!t]) { p = son[p][!t]; ans+= 1<<i; } 22 else p = son[p][t]; 23 } 24 return ans; 25 } 26 int main() 27 { 28 int n,maxn = 1<<31; 29 scanf("%d",&n); 30 for(int i=1;i<=n;i++) { scanf("%d",&a[i]); insert(a[i]); } 31 for(int i=1;i<=n;i++){//第一步只能枚举,无法优化 32 int ans = query(a[i]); 33 maxn = max(ans,maxn); 34 } 35 printf("%d\n",maxn); 36 return 0; 37 }