csu1216( Trie )

csu1216

题意

给定一些数,求这些数中两个数的异或值最大的那个值。

分析

转化成二进制数存入字典树,比如说要查询 (0011) ,显然和 (1100) 结合最优,所以我们直接在字典树上寻找 (1100) ,如果某一位没找到不管它继续往下找,因为我们是从高到低位存的,所以找得到的一定是最优的。

code

#include<cstdio>
#include<cstring>
#include<algorithm>
typedef long long ll;
using namespace std;
const int MAXN = 2e6 + 10;
int n;
int ans;
int bit[32];
struct Trie {
    int nxt[MAXN][2];
    int root, L;
    int newnode() {
        nxt[L][0] = nxt[L][1] = 0;
        return L++;
    }
    void init() {
        L = 1;
        root = newnode();
    }
    void insert(int x) {
        int tmp[32];
        memset(tmp, 0, sizeof tmp);
        int c = 0;
        while(x) {
            tmp[c++] = x % 2;
            x >>= 1;
        }
        int now = root;
        for(int i = 30; i >= 0; i--) {
            int d = tmp[i];
            if(!nxt[now][d]) nxt[now][d] = newnode();
            now = nxt[now][d];
        }
    }
    void query(int x) {
        int tmp[32];
        memset(tmp, 0, sizeof tmp);
        int c = 0;
        while(x) {
            tmp[c++] = !(x % 2);
            x >>= 1;
        }
        for(int i = c; i <= 30; i++) {
            tmp[i] = 1;
        }
        int now = root;
        int res = 0;
        for(int i = 30; i >= 0; i--) {
            int d = tmp[i];
            if(nxt[now][d]) res += bit[i];
            else d = !d;
            now = nxt[now][d];
        }
        ans = max(ans, res);
    }
}trie;
int main() {
    bit[0] = 1;
    for(int i = 1; i < 31; i++) {
        bit[i] = bit[i - 1] * 2;
    }
    while(~scanf("%d", &n)) {
        trie.init();
        ans = 0;
        for(int i = 0; i < n; i++) {
            int x;
            scanf("%d", &x);
            trie.query(x);
            trie.insert(x);
        }
        printf("%d
", ans);
    }
    return 0;
}
原文地址:https://www.cnblogs.com/ftae/p/7277149.html