裸的
xor
x
o
r
最小生成树。
枚举每一位,把这一位为
0
0
的放在一起形成一个连通块,为 的放在一起形成一个连通块,之间用字典树求一条最小边,然后分治做。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int M=6200000;
int k,n,m;
vector<int> g;
int Rt,nx[M][2],num;
void Insert(int& x,int y,int d) {
if(!x) x=++num,nx[x][0]=nx[x][1]=0;
if(d==-1) return;
Insert(nx[x][y>>d&1],y,d-1);
}
int Query(int x,int y,int d) {
if(d==-1) return 0;
int p=y>>d&1;
if(nx[x][p]) return Query(nx[x][p],y,d-1);
return Query(nx[x][p^1],y,d-1)+(1<<d);
}
ll Solve(vector<int>g,int d) {
if(!g.size()||d==-1) return 0;
vector<int> a[2];
for(int v:g) a[v>>d&1].push_back(v);
ll Ans=Solve(a[0],d-1)+Solve(a[1],d-1);
if(a[0].size()&&a[1].size()) {
Rt=num=0;
for(int v:a[0]) Insert(Rt,v,d-1);
int Res=1<<d;
for(int v:a[1]) Res=min(Res,Query(Rt,v,d-1));
Ans+=Res+(1<<d);
}
return Ans;
}
int main() {
scanf("%d",&n);
for(int i=1;i<=n;i++) {
int x;scanf("%d",&x);
g.push_back(x);
}
printf("%I64d\n",Solve(g,29));
return 0;
}