codeforces educational round 32 G xor-MST

G. Xor-MST
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

You 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 aixoraj.

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\n", 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\n", 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\n", t -> h, res);
    return res;
}
int main() {
    build();
    printf("%I64d\n", solve(&T));
    return 0;
}

  

posted @ 2017-11-10 18:21  hit_yjl  阅读(414)  评论(0编辑  收藏  举报