Codeforces 706D Vasiliy's Multiset(异或字典树)

来源:互联网 发布:清洁面膜有必要吗 知乎 编辑:程序博客网 时间:2024/06/05 08:48
转自:传送门
D. Vasiliy's Multiset
time limit per test
4 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

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 integerxi and some integer from the multiset A.

Example
Input
10+ 8+ 9+ 11+ 6+ 1? 3- 8? 3? 8? 11
Output
11101413
Note

After first five operations multiset A contains integers 089116 and 1.

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


题目大意:
    有一个开始只有0的集合,有3种操作,向集合中添加一个数字,删去集合中的一个数字,寻找输入数字与集合中的所有数字的最大异或值。

解题思路:
    新姿势get√
    据说这是一个经典的异或字典树,我们把每个数字的每一个二进制位拆开处理。最高位作根节点,插入和删除和普通字典树相同,对于查询,我们可以贪心的从高位往下找,如果这一位存在可以异或得到1的儿子,则沿这个儿子的方向向下走,否则沿另一个儿子的方向。

    O(Q*log len)。

#include<stdio.h>#include<iostream>#include<string.h>#define me(x) memset(x,0,sizeof(x))#define LL long long#define close() ios::sync_with_stdio(0); cin.tie(0);using namespace std;const int maxn=2e5+10;int next[maxn*32][2];LL val[maxn*32];int st;void init(){    me(next[0]);    me(val);    st=1;}void insert(LL x){    int u=0;    for(int i=32;i>=0;i--)    {        int c=((x>>i)&1);        if(!next[u][c])        {            me(next[st]);            next[u][c]=st++;        }        u=next[u][c];        ++val[u];    }}void _delete(LL x){    int u=0;    for (int i=32; i>=0; --i)    {        int c=((x>>i)&1);        u=next[u][c];        --val[u];    }}LL query(LL x){    int t=0;    LL ans=0;    for(int i=32;i>=0;i--)    {        int k=((x>>i)&1);        if(k==1)        {            if(next[t][0]&&val[next[t][0]])            {                ans+=1<<i;                t=next[t][0];            }            else t=next[t][1];        }        else        {            if(next[t][1]&&val[next[t][1]])            {                ans+=1<<i;                t=next[t][1];            }            else t=next[t][0];        }    }    return ans;}int main(){    int n;    close();    cin>>n;    init();    insert(0);    char op[5];int x;    while(n--)    {        cin>>op>>x;        if(op[0]=='+')            insert(x);        if(op[0]=='-')            _delete(x);        if(op[0]=='?')            cout<<query(x)<<endl;    }}


阅读全文
0 0
原创粉丝点击