Description
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.
Input
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.
Output
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.
Sample Input
10 + 8 + 9 + 11 + 6 + 1 ? 3 - 8 ? 3 ? 8 ? 11
11 10 14 13
Hint
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 .
博主种的第一颗树:
代码异常捉急。
思路:
数据量太大,只能用树存
#include <iostream>
#include <string.h>
#include <queue>
#include <cmath>
#include <cstdio>
#include <map>
#include <string>
#include <algorithm>
using namespace std;
typedef struct Node{
Node* last=NULL;
Node* next0=NULL;
Node* next1=NULL;
};
Node *root=new Node;
string tr(int b){
string str;
for(int i=0;i<=31;i++){
str+=b%2+'0';
b/=2;
}
reverse(str.begin(),str.end());
return str;
}
void add_p(string str){
Node *p=root;
for(int i=0;i<32;i++){
if(str[i]=='0'){
if(p->next0==NULL){
Node *temp=new Node;
temp->last=p;temp->next0=NULL;temp->next1=NULL;
p->next0=temp;
}
p=p->next0;
}else{
if(p->next1==NULL){
Node *temp=new Node;
temp->last=p;temp->next0=NULL;temp->next1=NULL;
p->next1=temp;
}
p=p->next1;
}
}
return ;
}
void delete_p(string str){
Node *p=root;
for(int i=0;i<32;i++){
if(str[i]=='0')
p=p->next0;
else
p=p->next1;
}
for(int i=31;i>=0;i--){
if(str[i]=='0'&&p->next0==NULL&&p->next1==NULL){
p=p->last;
delete(p->next0);
p->next0=NULL;
}else if(str[i]=='1'&&p->next0==NULL&&p->next1==NULL){
p=p->last;
delete(p->next1);
p->next1=NULL;
}
}
return ;
}
int suit_p(string str){
int ans=0;
Node *p=root;
for(int i=0;i<32;i++){
if(str[i]=='0') str[i]='1';
else str[i]='0';
}
for(int i=0;i<32;i++){
ans*=2;
if(str[i]=='1'){
if(p->next1!=NULL){ans+=1;p=p->next1;}
else {ans+=0;p=p->next0;}
}else{
if(p->next0!=NULL){ans+=0;p=p->next0;}
else {ans+=1;p=p->next1;}
}
}
return ans;
}
void clean(Node* x){
if(x->next0!=NULL) clean(x->next0);
if(x->next1!=NULL) clean(x->next1);
if(x->next0==NULL&&x->next1==NULL&&x!=root)
delete(x);
return ;
}
int main(){
int n;
cin>>n;
getchar();
map<int,int> flag;
clean(root);
add_p(tr(0));
while(n--){
char a;
int b;
scanf("%c %d",&a,&b);
getchar();
string str=tr(b);
if(a=='+'){
if(flag[b]==0) add_p(str);
flag[b]++;
}else if(a=='-'){
flag[b]--;
if(flag[b]==0) delete_p(str);
}else{
int ans=suit_p(str);
ans^=b;
cout<<ans<<endl;
}
}
return 0;
}