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中,把每一种数字都挂在字典树上,当删除a时,若multiset中无a,则在字典树上删除a.
给一个数b找一个最大的c(在集合中),使得c^b的值达到最大,直接在字典树上查询即可。
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <vector>
#include <map>
#include <set>
#define MOD 1000000007
using namespace std;
typedef long long ll;
struct Node{
int v;
Node *p[2];
};
multiset<int> s;
Node* NewNode(){
Node *m = new Node();
m -> p[0] = m -> p[1] = NULL;
return m;
}
void Insert(Node *k, int m){
for(int i = 30; i >= 0; i--){
if((1<<i)&m){
if(k -> p[1] == NULL)
k -> p[1] = NewNode();
k = k -> p[1];
}
else{
if(k -> p[0] == NULL)
k -> p[0] = NewNode();
k = k -> p[0];
}
}
k -> v = m;
}
int Query(Node *k, int m){
for(int i = 30; i >= 0; i--){
int d = (1<<i)&m;
d = d > 0 ? 1 : 0;
if(k -> p[d^1])
k = k -> p[d^1];
else
k = k -> p[d];
}
return k -> v;
}
void Delete(Node *k, int m, int d, int &sign){
if(k -> p[0] == NULL && k->p[1] == NULL){
sign = 1;
return ;
}
int h = m & (1<<d);
h = h > 0 ? 1 : 0;
Delete(k->p[h], m, d-1, sign);
if(sign == 1){
free(k->p[h]);
k -> p[h] = NULL;
}
if(k->p[h^1]){
sign = 0;
}
}
void Destory(Node *m){
if(m -> p[0])
Destory(m -> p[0]);
if(m -> p[1])
Destory(m -> p[1]);
free(m);
}
int main(){
// freopen("in.txt", "r", stdin);
int q, x;
char ch;
multiset<int> ::iterator iter;
scanf("%d ", &q);
Node *root = NewNode();
Insert(root, 0);
while(q--){
scanf("%c %d ", &ch, &x);
if(ch == '+'){
if(s.count(x) == 0){
Insert(root, x);
}
s.insert(x);
}
if(ch == '-'){
if(s.count(x) == 1){
int sign;
Delete(root, x, 30, sign);
}
iter = s.find(x);
s.erase(iter);
}
if(ch == '?'){
if(s.size() == 0){
printf("%d\n", x);
continue;
}
printf("%d\n", Query(root, x) ^ x);
}
}
Destory(root);
return 0;
}