新技能get啊。
以前都不知道这种用字典树搞。
关于字典树的入门可以看这个 http://blog.youkuaiyun.com/say_c_box/article/details/52073513
查询操作就是,找到可以让该位为1的儿子节点,向下访问。因为越高位是1数就越大嘛。
最多不过30层,所以直接建30层的树即可。
有一句一定要注意:Note, that the integer 0 will always be present in the set A.
#include <cstdio>
#include <cstring>
#include <string>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <string>
#include <cmath>
#include <cstdlib>
using namespace std;
const int MAXN =100000+10;
const long long INF =100000000000007;
struct node{
node *next[2];
int cnt;
node(){
memset(next,NULL,sizeof(next));
cnt=0;
}
};
node *p,*root=new node();
void _insert(int x){
p=root;
for(int i=30;i>=0;i--){
int num=x&(1<<i)?1:0;
if(p->next[num]==NULL)
p->next[num]=new node();
p=p->next[num];
p->cnt++;
}
}
void _delete(int x){
p=root;
for(int i=30;i>=0;i--){
int num=x&(1<<i)?1:0;
p=p->next[num];
p->cnt--;
}
}
int query(int x){
int res=0;
p=root;
for(int i=30;i>=0;i--){
int num=x&(1<<i)?0:1;
node *temp;
temp=p->next[num];
if(temp&&temp->cnt>0){
res+=pow(2.0,i);
p=temp;
}
else{
p=p->next[!num];
}
}
return res;
}
int main(){
int q;
_insert(0);
scanf("%d",&q);
getchar();
while(q--){
char op[2];
int x;
scanf("%s%d",op,&x);
if(op[0]=='+')
_insert(x);
else if(op[0]=='-')
_delete(x);
else
printf("%d\n",query(x));
}
return 0;
}