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
问题概述:你有一个的集合,一开始里面只有1个0,现有3种操作:
①向集合中添加一个数字;②删去集合中的一个数字(必须存在);
③给一个k,并在集合中找到一个数字使得它异或k最大,求这个最大异或值
http://codeforces.com/contest/706/problem/D
和 http://blog.youkuaiyun.com/jaihk662/article/details/53914302 大同小异,只不过多了添加和删除操作
#include<stdio.h>
typedef struct Trie
{
int sum;
Trie *next[2];
}Trie;
void Delete(Trie *root)
{
if(root->next[0])
Delete(root->next[0]);
if(root->next[1])
Delete(root->next[1]);
delete root;
}
void Create(Trie *root, int a, int c)
{
int now, i;
Trie *p = root;
for(i=30;i>=0;i--)
{
now = 0;
if(a&(1<<i))
now = 1;
if(p->next[now]==NULL)
{
Trie *temp = new Trie;
temp->next[0] = temp->next[1] = NULL;
temp->sum = 0;
p->next[now] = temp;
}
p = p->next[now];
p->sum += c;
}
}
int Query(Trie *root, int k)
{
int now, i, ans = 0;
Trie *p = root;
for(i=30;i>=0;i--)
{
now = 0;
if(k&(1<<i))
now = 1;
if(p->next[now^1] && p->next[now^1]->sum>0)
{
ans += (1<<i);
p = p->next[now^1];
}
else
p = p->next[now];
}
return ans;
}
int main(void)
{
int q, a;
char ch;
scanf("%d", &q);
Trie *root = new Trie;
root->next[0] = root->next[1] = NULL;
root->sum = 0;
Create(root, 0, 1);
while(q--)
{
scanf(" %c%d", &ch, &a);
if(ch=='+')
Create(root, a, 1);
if(ch=='-')
Create(root, a, -1);
if(ch=='?')
printf("%d\n", Query(root, a));
}
return 0;
}