引
T
r
i
e
树
Trie 树
Trie树 的新用法,(对我而言)
解法
题目实际就是让我们找所有配对方案中最大值的最小值,
从高到低 按位考虑 ,若当前为
1
1
1 的数有
k
k
k 个
k
k
k 为偶数时,两两抵消即可
k
k
k 为奇数时,那么当前位必定为
1
1
1 答案就为当前的最小异或和,可以用
T
r
i
e
树
Trie树
Trie树 求解
具体来说 , 将当前为为
1
1
1 的数加入
T
r
i
e
树
Trie 树
Trie树 ,再用当前位为
0
0
0 的数在树上查询,往相同的数的方向走,若没有就走另一个儿子且加上当前位的贡献
Code
#include <algorithm>
#include <iostream>
#include <cstring>
#include <vector>
#define bpt __builtin_popcount
#define rep(i, j, k) for (register int (i) = (j); (i) <= (k); (i)++)
#define _rep(i, j, k) for (register int (i) = (k); (i) >= (j); (i)--)
using ll = long long;
using namespace std;
#define pii pair<int, int>
#define pll pair<ll, ll>
const int N = 7e6 + 7;
int n;
struct Trie {
int son[N][2],tot=0;
void Clear() {
for(int i=1;i<=tot;i++) son[i][0]=son[i][1]=0;
tot=0;
}
void Insert(int x) {
int rt=0;
for(int i=29;~i;i--) {
int v=x>>i&1;
if(!son[rt][v]) son[rt][v]=++tot;
rt=son[rt][v];
}
}
int Query(int x) {
int rt=0,res=0;
for(int i=29;~i;i--) {
int v=x>>i&1;
if(son[rt][v]) rt=son[rt][v];
else res+=(1<<i),rt=son[rt][v^1];
}
return res;
}
}T;
int dfs(vector<int> a,int dep) {
if(dep<0 || a.size()==0) return 0;
vector<int> A,B;
for(int x:a) {
if(x>>dep&1) A.push_back(x);
else B.push_back(x);
}
if(A.size()&1) {
int res=2e9;
T.Clear();
for(int x:A) T.Insert(x);
for(int x:B) res=min(res,T.Query(x));
return res;
}else return max(dfs(A,dep-1),dfs(B,dep-1));
}
int main() {
scanf("%d",&n);
vector<int> a(n<<1) ;
for(int &x:a) scanf("%d",&x);
printf("%d\n",dfs(a,29));
}