Author has gone out of the stories about Vasiliy, so here is just a formal task description.
You are given qq queries and a multiset AA , initially containing only integer 00 . There are three types of queries:
- "+ x" — add integer xx to multiset AA .
- "- x" — erase one occurrence of integer xx from multiset AA . It's guaranteed that at least one xx is present in the multiset AA before this query.
- "? x" — you are given integer xx and need to compute the value , i.e. the maximum value of bitwise exclusive OR (also know as XOR) of integer xx and some integer yy from the multiset AA .
Multiset is a set, where equal elements are allowed.
题意:刚开始a集合里有一个数0,那么我们有q个操作:1.+x,将x加到集合a中,2.-x,将x从集合中减掉,3.?x,输出集合a中的数与x的最大异或值
思路:异或的话存二进制字典树,对插入操作就是平常的操作,因为还有一个删除和询问所以我们需要用个num数组记录一下一个数的二进制每个位的数的个数,删除的时候遍历一下num--,因为有询问操作所以我们要用一个数组v来记录一下到一个编号的数是多少
/*
.----------------. .----------------. .----------------. .----------------.
| .--------------. || .--------------. || .--------------. || .--------------. |
| | ________ | || | _________ | || | ____ ____ | || | ____ | |
| | |_ ___ `. | || | |_ ___ | | || ||_ \ / _|| || | .' `. | |
| | | | `. \ | || | | |_ \_| | || | | \/ | | || | / .--. \ | |
| | | | | | | || | | _| _ | || | | |\ /| | | || | | | | | | |
| | _| |___.' / | || | _| |___/ | | || | _| |_\/_| |_ | || | \ `--' / | |
| | |________.' | || | |_________| | || ||_____||_____|| || | `.____.' | |
| | | || | | || | | || | | |
| '--------------' || '--------------' || '--------------' || '--------------' |
'----------------' '----------------' '----------------' '----------------'
*/
#include<iostream>
#include<algorithm>
#include<cstring>
#include<vector>
#include<set>
#include<map>
#include<queue>
#include<deque>
#include<cmath>
#include<stack>
#define int long long
#define lowbit(x) x&(-x)
#define PI 3.1415926535
#define endl "\n"
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
int gcd(int a,int b){
return b>0 ? gcd(b,a%b):a;
}
/*
int dx[8]={-2,-2,-1,1,2,2,-1,1};
int dy[8]={-1,1,2,2,1,-1,-2,-2};
int dx[4]={0,-1,0,1};
int dy[4]={-1,0,1,0};
int dx[8]={-1,1,0,0,-1,-1,1,1};
int dy[8]={0,0,-1,1,-1,1,-1,1};
*/
//int e[N],ne[N],h[N],idx,w[N];
/*void add(int a,int b,int c){
e[idx]=b;
w[idx]=c;
ne[idx]=h[a];
h[a]=idx++;
}
*/
const int N=2e5+10;
int n;
int cnt;
int tr[N*17][2],num[N*27],v[N*27];//v是记录每个编号所表示的数字
void insert(int x){
int p=0;
for(int i=32;i>=0;i--){
int op=x>>i&1;
if(!tr[p][op]){
tr[p][op]=++cnt;
}
p=tr[p][op];
num[p]++;//对于每个位上的二进制数的编号,个数++
}
v[p]=x;//到最后的时候记录一下到达这个编号所表示的值
}
void declear(int x){//删除的是x的每一位二进制的数的编号的个数
int p=0;
for(int i=32;i>=0;i--){
int op=x>>i&1;
p=tr[p][op];
num[p]--;
}
}
int query(int x){
int p=0;
for(int i=32;i>=0;i--){
int op=x>>i&1;
if(tr[p][op^1]&&num[tr[p][op^1]]){//如果^1的数存在的话我们就让编号等于^1之后的数,否则还等于原数
p=tr[p][op^1];
}else p=tr[p][op];
}
return x^v[p];//返回异或值,v[p]表示我们最终找到的数的编号p所表示的数值
}
void sove(){
char op;
int x;
cin>>op>>x;
if(op=='+'){
insert(x);
}else if(op=='-'){
declear(x);
}else cout<<query(x)<<endl;
}
signed main(){
ios::sync_with_stdio(false);
cin.tie() ,cout.tie() ;
int t=1;
insert(0);
cin>>t;
while(t--){
sove();
}
return 0;
}