思路:
维护一个数组
cnt
,代表经过
Trie
每一个节点的数的数量,插入加
1
,删除减
询问时判断节点的 cnt 是否为0来决定该节点是否可走,然后尽量走与查询的数每一个二进制位相反的数。
代码:
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
inline int read(){
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
const int A = 2e5 + 10;
int Trie[A<<4][2],val[A<<4],cnt[A<<4],tot,x;
char s[5];
void insert(ll v,int add){
int u = 0;
for(int i=32 ;i>=0 ;i--){
int c = (v>>i)&1;
if(!Trie[u][c]) Trie[u][c] = ++tot;
u = Trie[u][c];
cnt[u] += add;
}
val[u] = v;
}
ll query(ll v){
int u = 0;
for(int i=32 ;i>=0 ;i--){
int c = (v>>i)&1;
if(cnt[Trie[u][c^1]]>0) u = Trie[u][c^1];
else u = Trie[u][c];
}
return 1LL*val[u];
}
int main(){
int q;q = read();
insert(0,1);
while(q--){
scanf("%s",s);x = read();
if(s[0] == '+') insert(x,1);else
if(s[0] == '-') insert(x,-1);else
printf("%I64d\n",1LL*x^query(x));
}
return 0;
}