G. Xor-MST
time limit per test
2 secondsmemory limit per test
256 megabytesinput
standard inputoutput
standard outputYou are given a complete undirected graph with n vertices. A number ai is assigned to each vertex, and the weight of an edge between vertices i and j is equal to ai xor aj.
Calculate the weight of the minimum spanning tree in this graph.
Input
The first line contains n (1 ≤ n ≤ 200000) — the number of vertices in the graph.
The second line contains n integers a1, a2, ..., an (0 ≤ ai < 230) — the numbers assigned to the vertices.
Output
Print one number — the weight of the minimum spanning tree in the graph.
Examples
input
5
1 2 3 4 5
output
8
input
4
1 2 3 4
output
8
建一颗01字典树,借用krustral的思想,优先选取全局最小边,最小边一定由一颗子树的两个点构成。故递归左右子树,再用字典树找一条连接左右树的边。
#include <iostream> #include <fstream> #include <sstream> #include <cstdlib> #include <cstdio> #include <cmath> #include <string> #include <cstring> #include <algorithm> #include <queue> #include <stack> #include <vector> #include <set> #include <map> #include <iomanip> #include <cctype> #include <cassert> #include <bitset> #include <ctime> using namespace std; #define pau system("pause") #define ll long long #define pii pair<int, int> #define pb push_back #define mp make_pair #define clr(a, x) memset(a, x, sizeof(a)) const double pi = acos(-1.0); const int INF = 0x3f3f3f3f; const int MOD = 1e9 + 7; const double EPS = 1e-9; struct trie { vector<int> vec; int h; trie *lson; trie *rson; } T; struct gg { vector<int> vec; } G; int n, a[200015]; const int K = 29; void ini(trie *t, int h) { (t -> vec).clear(); t -> h = h; t -> lson = t -> rson = NULL; } void build() { scanf("%d", &n); ini(&T, 30); trie *t = NULL; for (int i = 1; i <= n; ++i) { scanf("%d", &a[i]); t = &T; (t -> vec).pb(a[i]); for (int j = K; ~j; --j) { int f = a[i] >> j & 1; if (f) { if (NULL == t -> rson) { t -> rson = new trie; ini(t -> rson, j); } t = t -> rson; (t -> vec).pb(a[i]); } else { if (NULL == t -> lson) { t -> lson = new trie; ini(t -> lson, j); } t = t -> lson; (t -> vec).pb(a[i]); } } } } ll solve(trie *t) { int h = t -> h; if (!h) return 0; ll res = 0; if (t -> lson) { res += solve(t -> lson); //for (int i = 0; i < t -> lson -> vec.size(); ++i) printf("%d ", t -> lson -> vec[i]); //printf("h = %d, L, res = %d ", h - 1, res); } if (t -> rson) { res += solve(t -> rson); //for (int i = 0; i < t -> rson -> vec.size(); ++i) printf("%d ", t -> rson -> vec[i]); //printf("h = %d, R, res = %d ", h - 1, solve(t -> rson)); } if (t -> lson && t -> rson) { trie *lt = t -> lson, *rt = t -> rson; if (lt -> vec.size() < rt -> vec.size()) { int tmin = MOD << 1; for (int i = 0; i < lt -> vec.size(); ++i) { rt = t -> rson; int x = lt -> vec[i], y; for (int j = h - 2; ~j; --j) { if (!rt -> lson) rt = rt -> rson; else if (!rt -> rson) rt = rt -> lson; else { int f = x >> j & 1; if (f) rt = rt -> rson; else rt = rt -> lson; } } y = rt -> vec[0]; tmin = min(tmin, x ^ y); } res += tmin; } else { int tmin = MOD << 1; for (int i = 0; i < rt -> vec.size(); ++i) { lt = t -> lson; int x = rt -> vec[i], y; for (int j = h - 2; ~j; --j) { if (!lt -> lson) lt = lt -> rson; else if (!lt -> rson) lt = lt -> lson; else { int f = x >> j & 1; if (f) lt = lt -> rson; else lt = lt -> lson; } } y = lt -> vec[0]; tmin = min(tmin, x ^ y); } res += tmin; } } //for (int i = 0; i < t -> vec.size(); ++i) printf("%d ", t -> vec[i]); //printf("h = %d, res = %d ", t -> h, res); return res; } int main() { build(); printf("%I64d ", solve(&T)); return 0; }