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 .
题意:对于一个集合有三种操作:
1.添加一个数字x
2.删除一个数字x
3.给你一个数字x,在集合中找出一个数y使x^y最大,并输出y
这道题开始以为线段树,后来发现01字典树更好用一些,可惜自己并不会写……
对于这道题有一个贪心原则,就是找每一位尽量和当前数不一样的,异或才会更大
先贴一下代码,可以当01字典树模板用
#include<cstdio>
#include<iostream>
using namespace std;
const int maxn=30;
int n,tot=1;
struct wk{int NEXT[4],son;}trie[5000000];
void insert(int x){
int cur=1,i;
for(i=maxn;i>=0;i--){
int y=(x>>i)&1;
trie[cur].son++;
if(!trie[cur].NEXT[y])
trie[cur].NEXT[y]=++tot;
cur=trie[cur].NEXT[y];
}
trie[cur].son++;
}
void del(int x){
int cur=1,i;
for(i=maxn;i>=0;i--){
int y=(x>>i)&1;
if(!trie[cur].NEXT[y])return;
trie[cur].son--;
cur=trie[cur].NEXT[y];
}
trie[cur].son--;
}
int find(int x){
int cur=1,i,ans=0;
for(i=maxn;i>=0;i--){
int y=1^((x>>i)&1);
int temp=trie[cur].NEXT[y];
if(!temp||(!trie[temp].son))y^=1;
ans|=y<<i;
cur=trie[cur].NEXT[y];
}
return ans;
}
int main(){
int x;
char ch;
cin>>n;
insert(0);
while(n--){
cin>>ch>>x;
if(ch=='+')insert(x);
if(ch=='-')del(x);
if(ch=='?')printf("%d\n",x^find(x));
}
}