codeforces 706D Vasiliy's Multiset

D. Vasiliy's Multiset

 

Author has gone out of the stories about Vasiliy, so here is just a formal task description.

You are given q queries and a multiset A, initially containing only integer 0. There are three types of queries:

  1. "+ x" — add integer x to multiset A.
  2. "- x" — erase one occurrence of integer x from multiset A. It's guaranteed that at least one x is present in the multiset A before this query.
  3. "? x" — you are given integer x and need to compute the value , i.e. the maximum value of bitwise exclusive OR (also know as XOR) of integer x and some integer y from the multiset A.

Multiset is a set, where equal elements are allowed.

Input

The first line of the input contains a single integer q (1 ≤ q ≤ 200 000) — the number of queries Vasiliy has to perform.

Each of the following q lines of the input contains one of three characters '+', '-' or '?' and an integer xi (1 ≤ xi ≤ 109). It's guaranteed that there is at least one query of the third type.

Note, that the integer 0 will always be present in the set A.

Output

For each query of the type '?' print one integer — the maximum value of bitwise exclusive OR (XOR) of integer xi and some integer from the multiset A.

Example
input
10
+ 8
+ 9
+ 11
+ 6
+ 1
? 3
- 8
? 3
? 8
? 11
output
11
10
14
13
Note

After first five operations multiset A contains integers 0, 8, 9, 11, 6 and 1.

The answer for the sixth query is integer  — maximum among integers  and .

#include<cstdio>
#include<cmath>
#include<cstring>
using namespace std;
struct Trie
{
    Trie *next[2];
    int cnt;
    Trie()
    {
        next[0]=next[1]=0;
        cnt=0;
    }
};
Trie *rt=new Trie();
void _insert(int x)
{
    Trie *u=rt;
    for(int i=30;i>=0;i--)
    {
        int v=x&(1<<i)?1:0;
        if(u->next[v])
            u->next[v]->cnt++;
        else
        {
            Trie *p=new Trie();
            u->next[v]=p;
            p->cnt++;
        }
        u=u->next[v];
    }
}
void _delete(int x)
{
    Trie *u=rt;
    for(int i=30;i>=0;i--)
    {
        int v=x&(1<<i)?1:0;
        u->next[v]->cnt--;
        u=u->next[v];
    }
}
int query(int x)
{
    int res=0;
    Trie *u=rt;
    for(int i=30;i>=0;i--)
    {
        int v=x&(1<<i)?0:1;
        if(u->next[v]&&u->next[v]->cnt>0)
        {
            res+=pow(2.0,i);
            u=u->next[v];
        }
        else
            u=u->next[!v];
    }
    return res;
}
int main()
{
    _insert(0);
    int q;
    scanf("%d",&q);
    while(q--)
    {
        char c;
        int num;
        getchar();
        scanf("%c %d",&c,&num);
        if(c=='+')
            _insert(num);
        else if(c=='-')
            _delete(num);
        else
            printf("%d\n",query(num));
    }
    return 0;
}

 

posted on 2016-08-12 11:35    阅读(246)  评论(0编辑  收藏  举报

导航