Author has gone out of the stories about Vasiliy, so here is just a formal task description.
You are given q queries and a multiset A, initially containing only integer 0. There are three types of queries:
- "+ x" — add integer x to multiset A.
- "- x" — erase one occurrence of integer x from multiset A. It's guaranteed that at least one x is present in the multiset A before this query.
- "? x" — you are given integer x and need to compute the value , i.e. the maximum value of bitwise exclusive OR (also know as XOR) of integer x and some integer y from the multiset A.
Multiset is a set, where equal elements are allowed.
The first line of the input contains a single integer q (1 ≤ q ≤ 200 000) — the number of queries Vasiliy has to perform.
Each of the following q lines of the input contains one of three characters '+', '-' or '?' and an integer xi (1 ≤ xi ≤ 109). It's guaranteed that there is at least one query of the third type.
Note, that the integer 0 will always be present in the set A.
For each query of the type '?' print one integer — the maximum value of bitwise exclusive OR (XOR) of integer xi and some integer from the multiset A.
题目大意:
在一个预先只存有0的集合中有三个操作:
1. + 操作:向集合中存入一个元素 x
2. - 操作:从集合中删除一个元素 x
3. ? 操作:对集合中的所有元素与x进行或操作,输出最大值
解题思路:
因为要输出最大的值,因此集合中与x进行或操作的元素的位数一定最大,将位数从大到小排列,每位看做一层,用贪心的思路每层找与x在该层或操作为1的节点即可。
#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<string.h>
#include<vector>
#include<bitset>
#include<queue>
#include<stack>
#include<list>
#include<set>
#include<math.h>
#include<map>
using namespace std;
int n;
int d[8000000][2],cnt=1,num[8000000];//d中存储每个节点的编号,num中存储每个节点经过的次数
void add(int x)
{
int p=1;
for(int i=30;i>=0;i--)
{
if(d[p][(x>>i)&1]==0)
d[p][(x>>i)&1]=++cnt;
p=d[p][(x>>i)&1];
num[p]++;
}
}
void sub(int x)
{
int p=1;
for(int i=30;i>=0;i--)
{
p=d[p][(x>>i)&1];
num[p]--;
}
}
int fun(int x)
{
int ans=0,p=1;
for(int i=30;i>=0;i--)
{
int t=(x>>i)&1;
if(num[d[p][1^t]])
{
ans+=(1<<i);
p=d[p][1^t];
}
else p=d[p][t];
}
return ans;
}
int main()
{
freopen("in.txt","r",stdin);
freopen("out.txt","w",stdout);
scanf("%d",&n);
add(0);//按照题意需要先存0!
while(n--)
{
int x;
char c[3];
scanf("%s%d",c,&x);
if(c[0]=='+')
add(x);
if(c[0]=='-')
sub(x);
if(c[0]=='?')
printf("%d\n",fun(x));
}
return 0;
}