codeforces 706D. Vasiliy's Multiset 带删除操作的字典树(真模版)

来源:互联网 发布:matlab定义空矩阵 编辑:程序博客网 时间:2024/06/05 07:28
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 integerx from multiset A. It's guaranteed that at least onex 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 integery 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 setA.

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 multisetA.

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

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

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


题意:有一个集合,三种操作,+ x将x加入集合,- x 将集合中的x元素删除,? x,询问集合中与x异或的最大值。

集合中相同元素只需要插入一次就行了,用一个map来维护一下集合中相同元素的个数,删除同理。

字典树模版,带删除。

#include <bits/stdc++.h>using namespace std;const int N = 5000000+10;int ch[N][2];  ///存放这棵字典树int sz;        ///结点编号int ans;       ///答案int val[N];map<int,int> mp;void Init()    ///初始化{    sz = 1;    ans = 0;    memset(ch,0,sizeof ch);}void inssert(int num){   ///在字典树中插入一个数字    int u = 1;    val[u]++;    for(int i = 30;i >= 0;i--){        int c = (num>>i)&1;        if(!ch[u][c]){            ch[u][c] = ++sz;        }        u = ch[u][c];        val[u]++;    }}void lookfor(int num)    ///字典树中查找num的异或最大值{    int u = 1;    ans = 0;    for(int i = 30;i >= 0;i--){        int c = num&(1<<i);        if(c) c = 1;        if(val[ch[u][!c]]){ ///根据是否标记进行查找            ans |= (1<<i);            u = ch[u][!c];        }        else u = ch[u][c];    }}void erasee(int num)     ///删除就对标记的val--就行了{    int u = 1;    val[u]--;    for(int i = 30;i >= 0;i--){        int t = num&(1<<i);        int c;        if(t) c = 1;        else  c = 0;        if(c == 0) u = ch[u][0];        else       u = ch[u][1];        val[u]--;    }}int main(){    Init();    int q;    scanf("%d",&q);    while(q--){        inssert(0);        char s[2];        int x;        scanf("%s%d",s,&x);        if(s[0] == '+'){            mp[x]++;            if(mp[x] == 1)                inssert(x);        }        if(s[0] == '?'){            lookfor(x);            printf("%d\n",ans);        }        if(s[0] == '-'){            mp[x]--;            if(mp[x] == 0){                erasee(x);            }        }    }    return 0;}


0 0
原创粉丝点击