# CF888G Xor-MST

## code

/*
* @Author: wxyww
* @Date:   2019-08-18 19:36:04
*/
#include<cstdio>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<queue>
#include<vector>
#include<ctime>
using namespace std;
typedef long long ll;
const int N = 200100,INF = 1e9;
ll x=0,f=1;char c=getchar();
while(c<'0'||c>'9') {
if(c=='-') f=-1;
c=getchar();
}
while(c>='0'&&c<='9') {
x=x*10+c-'0';
c=getchar();
}
return x*f;
}
int tree[N * 31][2],a[N];
int n,tot;

int get(int x) {
for(int i = 29;i >= 0;--i) printf("%d",x >> i & 1);
puts("");
}
// get(x);
int p = 0;
for(int i = 29;i >= 0;--i) {
int k = x >> i & 1;
if(!tree[p][k]) tree[p][k] = ++tot;
p = tree[p][k];
}

}

int query(int x) {
// get(x);
int p = 0,ret = 0;
for(int i = 29;i >= 0;--i) {
int k = x >> i & 1;
if(!tree[p][1] && !tree[p][0]) return INF;
if(!tree[p][k]) {
ret += 1 << i;
p = tree[p][k ^ 1];
}
else p = tree[p][k];

}
// printf("%d\n",ret);
return ret;
}
ll solve(int l,int r,int pos) {
if(l > r) return 0;
// printf("%d %d %d\n",l,r,pos);
if(l == r || pos == -1) {
return 0;
}

int mid = r;
for(int i = l;i <= r;++i) {
if(a[i] >> pos & 1) {
mid = i - 1;break;
}
}

ll ret = 0;
ret += solve(l,mid,pos - 1);

int mn = INF;

for(int i = mid + 1;i <= r;++i) mn = min(mn,query(a[i]));

if(mn != INF) ret += mn;

for(int i = 0;i <= tot;++i) tree[i][0] = tree[i][1] = 0;
tot = 0;

ret += solve(mid + 1,r,pos - 1);

// for(int i = mid + 1;i <= r;++i) add(a[i]);
for(int i = l;i <= r;++i) add(a[i]);
// printf("%d\n",ret);
// printf("%d %d %d %d\n",l,r,pos,ret);
return ret;

}
int main() {
// freopen("1.in","r",stdin);
for(int i = 1;i <= n;++i) a[i] = read();

sort(a + 1,a + n + 1);

// for(int i = 1;i <= n;++i) get(a[i]);

// puts("");

cout<<solve(1,n,29);

return 0;
}

posted @ 2019-08-18 20:23  wxyww  阅读(...)  评论(...编辑  收藏