拿捏
2026-06-14 12:02:13
发布于:广东
5阅读
0回复
0点赞
#include <bits/stdc++.h>
using namespace std;
const int BIT = 30; // 2^30 > 1e9
const int MAXN = 200000 * 31; // 节点数上限
int trie[MAXN][2]; // 字典树节点
int cnt[MAXN]; // 节点计数
int tot = 1; // 当前节点数(0号节点作为根)
// 插入一个数
void insert(int x) {
int p = 0;
for (int i = BIT; i >= 0; i--) {
int bit = (x >> i) & 1;
if (!trie[p][bit]) {
trie[p][bit] = tot++;
}
p = trie[p][bit];
cnt[p]++;
}
}
// 删除一个数
void erase(int x) {
int p = 0;
for (int i = BIT; i >= 0; i--) {
int bit = (x >> i) & 1;
p = trie[p][bit];
cnt[p]--;
}
}
// 查询最大异或值
int query(int x) {
int p = 0;
int res = 0;
for (int i = BIT; i >= 0; i--) {
int bit = (x >> i) & 1;
// 优先走相反位
int want = bit ^ 1;
if (trie[p][want] && cnt[trie[p][want]]) {
res |= (1 << i);
p = trie[p][want];
} else {
p = trie[p][bit];
}
}
return res;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
int q;
cin >> q;
// 初始时插入0
insert(0);
while (q--) {
char op;
int x;
cin >> op >> x;
if (op == '+') {
insert(x);
} else if (op == '-') {
// 删除前先检查是否存在(题目允许不存在的删除)
// 简单方法:尝试删除,但必须保证cnt>0
// 这里需要检查,否则会删除不存在的节点导致cnt变负
int p = 0;
bool exist = true;
for (int i = BIT; i >= 0; i--) {
int bit = (x >> i) & 1;
if (!trie[p][bit] || !cnt[trie[p][bit]]) {
exist = false;
break;
}
p = trie[p][bit];
}
if (exist) {
erase(x);
}
} else { // '?'
cout << query(x) << '\n';
}
}
return 0;
}
这里空空如也








有帮助,赞一个