Acwing 143. 最大异或对

题意:n个数,求任意两个数的最大异或值。

思路:01前缀树

总结:确定了处理01最大异或问题时,采用先bitset<32>(x).to_string()再插入和计算的方式。 32位有符号整数的最大值应该是(1 << 31) - 1,而不是1 << 32位,1 << 32位代表这个1在第33位上。但是给bitset开的时候,要开到32位。此时最高位是1<<31,代表符号位。
所以如果确定是有符号整数,那么直接开31位,最高位32位是符号位,不开。那么最高位可以左移30位,以此类推。

字典树的节点中应该有个next数组.

struct Node{
    array<int, 2> next;
    Node(): next{0, 0}{}
};

class Trie{
public:
    Trie(): root_(0){
        trie_.resize(1);
    }

    void insert(const string& s){
        int cur = root_;
        for (const auto& x : s){
            int p = x - '0';
            if (trie_[cur].next[p] == 0){
                trie_[cur].next[p] = (int)trie_.size();
                trie_.emplace_back();
            }
            cur = trie_[cur].next[p];
        }
    }

    int get(const string& s){
        int cur = root_;
        int res = 0;
        int shift = 30;
        for (const auto& x : s){
            int p = x - '0';
            if (trie_[cur].next[!p]){
                cur = trie_[cur].next[!p];
                res += (1 << shift);
            }
            else if (trie_[cur].next[p]){
                cur = trie_[cur].next[p];
            }
            else{
                break;
            }
            shift --;
        }
        return res;
    }

private:
    int root_;
    vector<Node> trie_;
};

void preProcess(){

}



void solve(){
    int n;
    cin >> n;

    vector<int> a(n);
    int ans = 0;
    Trie trie{};
    for (auto& x : a){
        cin >> x;
        string s = bitset<31>(x).to_string();
        ans = max(ans, trie.get(s));
        trie.insert(s);
    }

    cout << ans << endl;
}
posted @ 2024-05-07 13:51  _Yxc  阅读(7)  评论(0编辑  收藏  举报