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:
- "+ x" — add integer x to multiset A.
- "- 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.
- "? 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.
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.
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.
10 + 8 + 9 + 11 + 6 + 1 ? 3 - 8 ? 3 ? 8 ? 11
11 10 14 13
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 .
题意: + 向集合里加入元素,- 从集合里删除元素, ? 求x与集合里元素的最大值和本身比较的最大值。
思路: 01 字典树模板题
#include<bits/stdc++.h>
using namespace std;
#define Memset(x, a) memset(x, a, sizeof(x))
typedef long long ll;
const int maxn = 200000 + 5;//集合中的数字个数
int ch[32*maxn][2]; //节点的边信息
ll val[32*maxn]; //节点存储的值
int sz; //树中当前节点个数
int num[32*maxn];
void init(){
Memset(ch[0],0); //树清空
memset(num,0,sizeof(num));
sz=1;
}
void _insert(ll a){//在字典树中插入 a
//和一般字典树的操作相同 将X的二进制插入到字典树中
int rt=0;
for(int i=32;i>=0;i--){
int c=((a>>i)&1);
if(!ch[rt][c]){
Memset(ch[sz],0);
val[sz]=0;
num[sz]=0;
ch[rt][c]=sz++;
}
rt=ch[rt][c];
num[rt]++;
}
val[rt]=a; //最后的节点插入value
}
ll query(ll a){ //在字典树中查找和a异或的值最大的元素b 返回b的值
int rt=0;
for(int i=32;i>=0;i--){
int c=((a>>i)&1);
if(ch[rt][c^1]&&num[ch[rt][c^1]]) rt=ch[rt][c^1];//c=0,b=c^1=1,b^c=1;c=1,b=c^1=0,b^c=1;
else rt=ch[rt][c];
}
return val[rt];
}
void update(ll a,int d)
{
int rt=0;
for(int i=32;i>=0;i--)
{
int c=((a>>i)&1);
rt=ch[rt][c];
num[rt]+=d;
}
return ;
}
char op[5];
int x;
int main()
{
int q;
init();
scanf("%d",&q);
while(q--)
{
scanf("%s %d",op,&x);
if(op[0]=='+'){
_insert((ll)x);
}
else if(op[0]=='-'){
update((ll)x,-1);
}
else{
ll ans=query((ll)x);
//cout<<ans<<endl;
ans=ans^x;
ans=max(ans,(ll)x);
cout<<ans<<endl;
}
}
return 0;
}