D. Vasiliy's Multiset
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 .
得学姐指导----涉及到XOR的建树都建字典树。
哇哈哈~
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <cmath> using namespace std; const int maxn = 5e6+5; struct node { int next[5]; int v; }; node tree[maxn]; int sz = 1; void build(int x,int v) { int root = 0; for(int i=31;i>=0;i--) { int id = (x>>i)&1; if(tree[root].next[id]==0) { memset(tree[sz].next,0,sizeof(tree[sz].next)); tree[sz].v = 0; tree[root].next[id] = sz++; } root = tree[root].next[id]; tree[root].v+=v; } } void match(int x) { int root = 0; x = ~x; int ans = 0; for(int i=31;i>=0;i--) { ans *= 2; int id = (x>>i)&1; if(tree[root].next[id]&&tree[tree[root].next[id]].v) { ans++; root = tree[root].next[id]; } else { root = tree[root].next[1-id]; } } printf("%d ",ans); } int main() { int n,x; char s[3]; cin>>n; /* for(int i=0;i<=maxn-1;i++) { tree[i].v = 0; memset(tree[i].next,0,sizeof(tree[i].next)); }*/ build(0,1); for(int i=1;i<=n;i++) { scanf("%s %d",s,&x); if(s[0]=='+') { build(x,1); } else if(s[0]=='-') { build(x,-1); } else { match(x); } } return 0; }