Codeforces Round #367 (Div. 2) D Vasiliy's Multiset(01Trie)

来源:互联网 发布:淘宝初始流量为0 编辑:程序博客网 时间:2024/05/19 00:09

字典树裸题。之前做过类似的,把代码拿过来提交,居然wa了。调了半天,发现以前的代码,是错的。。。这里写图片描述
把每个数字的二进制,扩充到31位,然后插入字典树。对于当前的数,对于他的每一位,每次在树中匹配和他相反的那一位,从高位到低位匹配。最后得到的就是异或最大值。

#include <bits/stdc++.h>using namespace std;const int MAXN = 2e5+10;struct MyTrie{    int next[MAXN*32][2];    int cnt[MAXN*32];    int root,sz;    void init()    {        memset(next,-1,sizeof(next));        memset(cnt,0,sizeof(cnt));        root = sz = 0;    }    void insert(int num)    {        int now = root;        for(int i = 30; i >= 0; --i)        {            int t = (num>>i)&1;            if(next[now][t] == -1)                next[now][t] = ++sz;            cnt[next[now][t]]++;            now = next[now][t];        }    }    void erase(int num)    {        int now = root;        for(int i = 30; i >= 0; --i)        {            int t = (num>>i)&1;            cnt[next[now][t]]--;            int pre = next[now][t];            if(cnt[next[now][t]] == 0)                next[now][t] = -1;            now = pre;        }    }    int query(int num)    {        int ret = 0,t;        int now = root;        for(int i = 30; i >= 0; --i)        {            t = (num>>i)&1;            if(next[now][!t] != -1)            {                t = !t;                ret |= (1<<i);            }            else if(next[now][t] != -1)                ret |= (0<<i);            else                return num;            now = next[now][t];        }        return ret;    }}Trie;int main(){    int q;    scanf("%d",&q);    char op;    int num;    Trie.init();    Trie.insert(0);    while(q--)    {        scanf(" %c %d",&op,&num);        if(op == '+')            Trie.insert(num);        else if(op == '-')            Trie.erase(num);        else            printf("%d\n",Trie.query(num));    }    return 0;}
阅读全文
0 0