题目大意:给你n( n ≤ 1 e 5 n\leq1e5 n≤1e5)个整数.让你确定一个整数X最小化 max { a i ⊕ X } \max\{a_i\oplus X\} max{ ai⊕X}
题目思路:
二进制从高位到低位考虑.当第 i i i位同时存在’0’和’1’时,贡献恒为 2 i 2^{i} 2i.这一位放0/1就只需要考虑另一半的值了.
例如:X的第 i i i位放0.那么那些 [本位为0的数]与x作异或都会比 [本位为1的数]与x作异或 要小了.所以接下来我们只需要考虑那些 [本位为1的数].反之亦然.所以这里形成两个不同的决策(要么填1要么填0嘛).我们可以递归求解,然后取两者的最小值即可.
然后当本位只存在’0’ 或 只存在’1’ 时,X填相同的值,贡献就为0了.
所以用01Trie存储序列.dfs跑一下求答案即可.
AC代码:
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int maxn = 4e6;
namespace Trie{
int tr[maxn][2] , v[maxn] , tot;
void add (int x){
int u = 0;v[u]++;
for (int i = 30 ; i >= 0 ; i--){
int g = ((x >> i) & 1);
if (!tr[u][g]) tr[u][g] = ++tot;
u = tr[u][g];
v[u]++;
}
}
ll dfs (int u , int pos)
{
if (pos == -1) return 0;
if (tr[u][0] && tr[u][1]) return min (dfs(tr[u][0] , pos - 1) , dfs(tr[u][1] , pos - 1)) + (1ll << pos);
if (tr[u][0]) return dfs (tr[u][0] , pos - 1);
return dfs (tr[u][1] , pos - 1);
}
}
int main()
{
ios::sync_with_stdio(false);
int n; cin >> n;
for (int i = 1; i <= n ; i++){
int x;cin >> x; Trie::add(x);
}
cout << Trie::dfs (0 , 30) << endl;
return 0;
}