Codeforces Round #367 (Div. 2) D——Vasiliy's Multiset(异或字典树)
2016-08-12 13:45
621 查看
D. Vasiliy's Multiset
time limit per test
4 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output
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.
Example
input
output
Note
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
.
新技能get啊。
以前都不知道这种用字典树搞。
关于字典树的入门可以看这个 http://blog.csdn.net/say_c_box/article/details/52073513
查询操作就是,找到可以让该位为1的儿子节点,向下访问。因为越高位是1数就越大嘛。
最多不过30层,所以直接建30层的树即可。
有一句一定要注意:Note, that the integer 0 will
always be present in the set A.
#include <cstdio>
#include <cstring>
#include <string>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <string>
#include <cmath>
#include <cstdlib>
using namespace std;
const int MAXN =100000+10;
const long long INF =100000000000007;
struct node{
node *next[2];
int cnt;
node(){
memset(next,NULL,sizeof(next));
cnt=0;
}
};
node *p,*root=new node();
void _insert(int x){
p=root;
for(int i=30;i>=0;i--){
int num=x&(1<<i)?1:0;
if(p->next[num]==NULL)
p->next[num]=new node();
p=p->next[num];
p->cnt++;
}
}
void _delete(int x){
p=root;
for(int i=30;i>=0;i--){
int num=x&(1<<i)?1:0;
p=p->next[num];
p->cnt--;
}
}
int query(int x){
int res=0;
p=root;
for(int i=30;i>=0;i--){
int num=x&(1<<i)?0:1;
node *temp;
temp=p->next[num];
if(temp&&temp->cnt>0){
res+=pow(2.0,i);
p=temp;
}
else{
p=p->next[!num];
}
}
return res;
}
int main(){
int q;
_insert(0);
scanf("%d",&q);
getchar();
while(q--){
char op[2];
int x;
scanf("%s%d",op,&x);
if(op[0]=='+')
_insert(x);
else if(op[0]=='-')
_delete(x);
else
printf("%d\n",query(x));
}
return 0;
}
time limit per test
4 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output
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.
Example
input
10 + 8 + 9 + 11 + 6 + 1 ? 3 - 8 ? 3 ? 8 ? 11
output
11 10 14 13
Note
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
.
新技能get啊。
以前都不知道这种用字典树搞。
关于字典树的入门可以看这个 http://blog.csdn.net/say_c_box/article/details/52073513
查询操作就是,找到可以让该位为1的儿子节点,向下访问。因为越高位是1数就越大嘛。
最多不过30层,所以直接建30层的树即可。
有一句一定要注意:Note, that the integer 0 will
always be present in the set A.
#include <cstdio>
#include <cstring>
#include <string>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <string>
#include <cmath>
#include <cstdlib>
using namespace std;
const int MAXN =100000+10;
const long long INF =100000000000007;
struct node{
node *next[2];
int cnt;
node(){
memset(next,NULL,sizeof(next));
cnt=0;
}
};
node *p,*root=new node();
void _insert(int x){
p=root;
for(int i=30;i>=0;i--){
int num=x&(1<<i)?1:0;
if(p->next[num]==NULL)
p->next[num]=new node();
p=p->next[num];
p->cnt++;
}
}
void _delete(int x){
p=root;
for(int i=30;i>=0;i--){
int num=x&(1<<i)?1:0;
p=p->next[num];
p->cnt--;
}
}
int query(int x){
int res=0;
p=root;
for(int i=30;i>=0;i--){
int num=x&(1<<i)?0:1;
node *temp;
temp=p->next[num];
if(temp&&temp->cnt>0){
res+=pow(2.0,i);
p=temp;
}
else{
p=p->next[!num];
}
}
return res;
}
int main(){
int q;
_insert(0);
scanf("%d",&q);
getchar();
while(q--){
char op[2];
int x;
scanf("%s%d",op,&x);
if(op[0]=='+')
_insert(x);
else if(op[0]=='-')
_delete(x);
else
printf("%d\n",query(x));
}
return 0;
}
相关文章推荐
- 【Codeforces Round 367 (Div 2) D】【字典树典型题】Vasiliy's Multiset
- Codeforces Round #367 (Div. 2) D Vasiliy's Multiset(字典树)
- Codeforces Round #367 (Div. 2) Vasiliy's Multiset(字典树)
- Codeforces Round #367 (Div. 2)-Vasiliy's Multiset-最大异或和-trie
- Codeforces Round #367 (Div. 2) D. Vasiliy's Multiset(01字典树求最大异或值)
- Codeforces Round #367 (Div. 2) D. Vasiliy's Multiset(字典树模板)
- 【 Codeforces Round #367 (Div. 2) D】 Vasiliy's Multiset (Trie 按数位建字典树)
- CF#367(Div2)D. Vasiliy's Multiset (字典树)
- Codeforces Round #367 (Div. 2) Vasiliy's Multiset 异或字典树带删除模板
- Codeforces Round #367 (Div. 2) D Vasiliy's Multiset(字典树+贪心)
- Codeforces Round #367 (Div. 2) D. Vasiliy's Multiset (字典树二进制)
- Codeforces Round #367 (Div. 2):Vasiliy's Multiset(01字典树)
- Codeforces Round #367 (Div. 2) [D] Vasiliy's Multiset(01字典树模板)
- Codeforces Round #470 Div. 2 D Perfect Security(字典树求异或最小 唯一)
- Codeforces Round #367 (Div. 2)D. Vasiliy's Multiset (字典树)
- Vasiliy's Multiset (异或字典树)
- Codeforces Round #367 (Div. 2) D Vasiliy's Multiset(查找树)
- Vasiliy's Multiset CodeForces - 706D 字典树
- Codeforces Round #367 (Div. 2) D. Vasiliy's Multiset (tire 树)
- Codeforces Round #367 (Div. 2) D Vasiliy's Multiset(01Trie)