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;
}