Binary from high to Low Division, current division to the first I-bit
Then it must be put the first I i bit 0 together, for 1 of the put together, the two pieces into a unicom block, and then a side is the best
Two pieces of the rule go down.
Look for the smallest side, build a dictionary tree on the other side, and look for the number on the dictionary tree.
#include <cstdio> #include <iostream> #include <algorithm> using namespace std;
const int n=100010;
typedef long Long LL;
int n,cnt,a[n],nxt[n*50][2];
ll ans; void Add (int cur,int x) {for (int i=30;~i;i--) {if (!nxt[cur][x>>i&1]) NXT[CUR][X>>I&1]=++CN
T
cur=nxt[cur][x>>i&1];
}} int Query (int cur,int x) {int ret=0;
for (int i=30;~i;i--) {if (nxt[cur][x>>i&1]) cur=nxt[cur][x>>i&1];
else ret+=1<<i,cur=nxt[cur][~x>>i&1];
} return ret;
} int LC;
inline BOOL CMP (const int &A,CONST int &b) {return (a>>lc&1) < (b>>lc&1);}
int Merge (int x,int y) {if (!x | |!y) return x+y;
Nxt[x][0]=merge (Nxt[x][0],nxt[y][0]);
Nxt[x][1]=merge (nxt[x][1],nxt[y][1]);
return x; } int solve (int l,int r,int t) {if (!t) {int ro=++cnt;
ADD (Ro,a[l]);
return ro; } lc=t-1;
Sort (a+l,a+1+r,cmp); int miD=L-1; for (int i=l;i<=r;i++) if (a[i]>>lc&1) break;
else mid=i;
int lro=0,rro=0,cur=1<<30;
if (l<=mid) lro=solve (l,mid,t-1);
if (mid+1<=r) rro=solve (mid+1,r,t-1);
for (int i=l;i<=mid;i++) cur=min (Cur,query (Rro,a[i]));
if (mid<l | | mid>=r) cur=0;
Ans+=cur;
Return Merge (Lro,rro);
} int main () {scanf ("%d", &n);
for (int i=1;i<=n;i++) scanf ("%d", &a[i]);
Solve (1,n,31);
cout<<ans<<endl;
return 0; }