• 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
    ", 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;
    }
    

      

  • 相关阅读:
    LOJ#6031. 「雅礼集训 2017 Day1」字符串
    LG P4768 [NOI2018] 归程
    LG P3250 [HNOI2016]网络
    BZOJ4644 经典傻逼题
    LG P4373 [USACO18OPEN]Train Tracking P
    CF1375H Set Merging
    LG P6541 [WC2018]即时战略
    CF1097G Vladislav and a Great Legend
    python学习笔记-基本概念
    python学习笔记十-文件操作
  • 原文地址:https://www.cnblogs.com/BIGTOM/p/7815934.html
Copyright © 2020-2023  润新知