记 $n$ 为元素个数。
Trie 的空间复杂度是 $O(n \log n)$ 的。因此本题如果把空间限制开到 $16\text{MB}$ 可以使得 Trie 无法通过。
这里介绍一种时间复杂度 $O(n \log^2 n)$、空间复杂度 $O(n)$ 的做法。
使用 multiset 来维护这个数集。那么关键在于查询。
考虑从高位到低位贪。假设当前贪到第 $i$ 位。可以发现,优先选第 $i$ 位不同的,如果存在就把第 $i$ 位定了继续往下做。每次查询的都是是否存在值位于某个区间内的数。可以使用 multiset 查询大于等于区间左端点最小的数,判断是否小于等于右端点。
常数较小,实现较为简单。
#include<bits/stdc++.h>
using namespace std;
multiset<int> S;
int n, op, x;
int main(){
ios::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
S.insert(0);
cin >> n;
while (n--){
cin >> op >> x;
if (op == 1) S.insert(x);
else if (op == 2) S.erase(S.find(x));
else{
int res = 0;
for (int i = 30; ~i; i--){
int l = x >> i + 1 << i + 1 | ~x & 1 << i, r = l + (1 << i) - 1;
auto it = S.lower_bound(l);
if (it != S.end() && *it <= r)
x ^= 1 << i, res ^= 1 << i;
}
cout << res << "\n";
}
}
return 0;
}