给出很多操作,能向一个集合里增加元素,也能减少元素,查询某一个值在这个集合里的最大异或值
01字典树,在节点上新开一个记录节点出现的次数,查询的时候用次数做判断,没有出现的话就相当与没有这个节点就好了。
#include <stdio.h>
#include <algorithm>
using namespace std;
const int N=200005;
struct node
{
int val[2];
int k;
}tree[N*40];
int tot;
long long int ans=0;
int newnode()
{
tot++;
tree[tot].val[0]=tree[tot].val[1]=0;
tree[tot].k=0;
return tot;
}
void ins(int x)
{
int root=0;
for(int i=31;i>=0;i--)
{
int temp=!!(x&(1<<i));
if(tree[root].val[temp]==0)
tree[root].val[temp]=newnode();
tree[tree[root].val[temp]].k++;
root=tree[root].val[temp];
}
}
void query(int x)
{
int root=0;
for(int i=31;i>=0;i--)
{
int temp=!!!(x&(1<<i));
if(tree[root].val[temp]!=0&&tree[tree[root].val[temp]].k>=1)
{
ans+=temp*(1<<i);
root=tree[root].val[temp];
}
else
{
ans+=(!temp)*(1<<i);
root=tree[root].val[!temp];
}
}
}
void decc(int x)
{
int root=0;
for(int i=31;i>=0;i--)
{
int temp=!!(x&(1<<i));
tree[tree[root].val[temp]].k--;
root=tree[root].val[temp];
}
}
int main()
{
int n;
scanf("%d",&n);
ins(0);
while(n--)
{
char sym;
int x;
ans=0;
scanf(" %c %d",&sym,&x);
if(sym=='+')
{
ins(x);
}
if(sym=='?')
{
query(x);
printf("%lld\n",ans^x);
}
if(sym=='-')
{
decc(x);
}
}
return 0;
}