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.
10 + 8 + 9 + 11 + 6 + 1 ? 3 - 8 ? 3 ? 8 ? 11
11 10 14 13
After first five operations multiset A contains integers 0, 8, 9, 11, 6 and 1.
The answer for the sixth query is integer — maximum among integers
,
,
,
and
.
题意
给一个multiset,初始时有一个元素0,三种操作:1.添加一个数 2.删除一个数 3.求集合内与给定的数异或最大值
题解
对multiset中的数维护一个字典树,每次贪心取,详细见代码。
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<vector>
using namespace std;
typedef long long ll;
const int MAXN=3200000;
struct tree
{
int sz;
int node[MAXN][2],sum[MAXN]; //sum记录该结点出现次数
tree(){memset(node,0,sizeof(node)),memset(sum,0,sizeof(sum)),sz=1;}
void add(int x)
{
int now=1;
for(int i=30;i>=0;i--)
{
if(x&(1<<i))
{
if(!node[now][1])
node[now][1]=++sz;
now=node[now][1];
sum[now]++;
}
else
{
if(!node[now][0])
node[now][0]=++sz;
now=node[now][0];
sum[now]++;
}
}
}
void del(int x)
{
int now=1;
for(int i=30;i>=0;i--)
{
if(x&(1<<i))
now=node[now][1],sum[now]--;
else
now=node[now][0],sum[now]--;
}
}
ll query(int x)
{
ll ans=0;
int now=1;
for(int i=30;i>=0;i--)
{
if(x&(1<<i)) //该位为1,如果能取0就取0,并更新答案
{
if(sum[node[now][0]]) ans|=(1<<i),now=node[now][0];
else now=node[now][1];
}
else
{
if(sum[node[now][1]]) ans|=(1<<i),now=node[now][1];
else now=node[now][0];
}
}
return ans;
}
}P;
int main()
{
int q;
scanf("%d",&q);
P.add(0); //注意这个!
while(q--)
{
char s[10];
scanf("%s",s);
int x;
scanf("%d",&x);
if(s[0]=='+') P.add(x);
else if(s[0]=='-') P.del(x);
else
{
ll ans=P.query(x);
printf("%I64d\n",ans);
}
}
return 0;
}