给出很多操作,能向一个集合里增加元素,也能减少元素,查询某一个值在这个集合里的最大异或值
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;
}
本文介绍了一种使用01字典树的数据结构来高效处理元素的增删操作,并支持查询集合中与指定值的最大异或值的问题。通过节点计数优化查询过程,确保了算法的有效性和快速响应。
&spm=1001.2101.3001.5002&articleId=79518835&d=1&t=3&u=e576e62c834743b096ec3f77f1d209a1)
707

被折叠的 条评论
为什么被折叠?



