全部评论 1

  • #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;
    

    }

    2026-09-11 来自 浙江

    0
暂无数据

提交答案之后,这里将显示提交结果~

首页