Codeforces Round #367 (Div. 2) D. Vasiliy's Multiset (0/1-Trie树)
Vasiliy's Multiset
题目链接:
http://codeforces.com/contest/706/problem/D
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.
</big>
##Input
<big>
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.
</big>
##Output
<big>
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.
</big>
##Examples
<big>
input
10
- 8
- 9
- 11
- 6
- 1
? 3
- 8
? 3
? 8
? 11
output
11
10
14
13
</big>
##Source
<big>
Codeforces Round #367 (Div. 2)
</big>
<br/>
##题意:
<big>
维护一个multiset:
操作1:插入一个数字
操作2:删除指定数字
操作3:给出一个x,求集合中的一个元素y,使得 x XOR y 最大.
</big>
<br/>
##题解:
<big>
由于异或前后的值不能保持单调性,所以排序和线段树都不好处理.
这里需要用一个 0/1-Trie树 来维护.
对于集合中的数用二叉树中的结点来表示其二进制位.
①插入:开辟一些新的树结点.
②删除:找到对应结点赋成NULL. 删除时有几点需要注意:
集合允许重复,所以可以记录每个数出现的次数,当集合中仅有一个x时才删除.
把最底端的叶节点删除后,要递归更新其父结点的状态,否则在匹配时可能会进入不存在的结点.
③匹配:先把x按位取反,从高位到低位在二叉树中匹配x,按能匹配时尽量匹配的原则往下走. 这样可以保证结果从高位到低位有尽量多的位不相同,即异或结果最大.
注意:初始时集合中有个0,一开始忘了这个,RE了2发.
</big>
<br/>
##代码:
``` cpp
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <queue>
#include <map>
#include <set>
#include <stack>
#include <vector>
#include <list>
#define LL long long
#define eps 1e-8
#define maxn 101000
#define mod 100000007
#define inf 0x3f3f3f3f
#define mid(a,b) ((a+b)>>1)
#define IN freopen("in.txt","r",stdin);
using namespace std;
class Trie
{
public:
Trie *next[2];
Trie() {
memset(next,NULL,sizeof(next));
}
};
Trie *root;
void Insert(LL n)
{
Trie *p = root;
for(int i=31;i>=0;i--)
{
int id = (n >> i) & 1;
if(p->next[id] == NULL)
p->next[id] = new Trie();
p = p->next[id];
}
}
int Delete(Trie *p, LL n, int i)
{
if(i < 0) return 1;
int id = (n >> i) & 1;
int ret = Delete(p->next[id], n, i-1);
if(ret) p->next[id] = NULL;
if(p->next[0] == NULL && p->next[1] == NULL)
return 1;
return 0;
}
LL Match(LL m)
{
m = ~m;
LL ans = 0;
Trie *p = root;
for(int i=31;i>=0;i--) {
ans <<= 1;
int bit = (m >> i) & 1;
if(bit) {
if(p->next[1]) {
p = p->next[1];
ans++;
}
else {
p = p->next[0];
}
}
else {
if(p->next[0]) {
p = p->next[0];
}
else {
p = p->next[1];
ans++;
}
}
}
return ans;
}
map<LL, int> occ;
int main(int argc, char const *argv[])
{
//IN;
int q;
while(scanf("%d", &q) != EOF)
{
root = new Trie();
occ.clear();
Insert(0LL);
occ[0] = 1;
while(q--)
{
getchar();
char op; LL val;
op = getchar();
scanf("%I64d", &val);
if(op == '+') {
if(!occ[val]) {
occ[val] = 1;
Insert(val);
}
else occ[val]++;
}
else if(op == '-') {
if(occ[val] == 1) Delete(root, val, 31);
occ[val]--;
} else {
printf("%I64d\n", Match(val)^val);
}
}
}
return 0;
}
Codeforces Round #367 (Div. 2) D. Vasiliy's Multiset (0/1-Trie树)的更多相关文章
- Codeforces Round #367 (Div. 2) D. Vasiliy's Multiset(01字典树求最大异或值)
http://codeforces.com/contest/706/problem/D 题意:有多种操作,操作1为在字典中加入x这个数,操作2为从字典中删除x这个数,操作3为从字典中找出一个数使得与给 ...
- Codeforces Round #367 (Div. 2) D. Vasiliy's Multiset
题目链接:Codeforces Round #367 (Div. 2) D. Vasiliy's Multiset 题意: 给你一些操作,往一个集合插入和删除一些数,然后?x让你找出与x异或后的最大值 ...
- Codeforces Round #367 (Div. 2) D. Vasiliy's Multiset Trie
题目链接: http://codeforces.com/contest/706/problem/D D. Vasiliy's Multiset time limit per test:4 second ...
- Codeforces Round #367 (Div. 2) D. Vasiliy's Multiset(可持久化Trie)
D. Vasiliy's Multiset time limit per test 4 seconds memory limit per test 256 megabytes input standa ...
- Codeforces Round #367 (Div. 2)D. Vasiliy's Multiset (字典树)
D. Vasiliy's Multiset time limit per test 4 seconds memory limit per test 256 megabytes input standa ...
- Codeforces Round #367 (Div. 2) D. Vasiliy's Multiset trie树
D. Vasiliy's Multiset time limit per test 4 seconds memory limit per test 256 megabytes input standa ...
- Codeforces Round #367 (Div. 2) C. Hard problem(DP)
Hard problem 题目链接: http://codeforces.com/contest/706/problem/C Description Vasiliy is fond of solvin ...
- Codeforces Round #367 (Div. 2) B. Interesting drink (模拟)
Interesting drink 题目链接: http://codeforces.com/contest/706/problem/B Description Vasiliy likes to res ...
- Codeforces Round #367 (Div. 2) A. Beru-taxi (水题)
Beru-taxi 题目链接: http://codeforces.com/contest/706/problem/A Description Vasiliy lives at point (a, b ...
随机推荐
- 浅谈网络爬虫爬js动态加载网页(三)
上一篇讨论了web driver对动态网页的抓取与分析,可以很清楚的看出这是一种集中式处理方式,简单说,就是利用服务器,打开一个真正的brower,然后将需要解析的地址交给浏览器,浏览器去解析,然后将 ...
- UVALive 3989 Ladies' Choice(稳定婚姻问题:稳定匹配、合作博弈)
题意:男女各n人,进行婚配,对于每个人来说,所有异性都存在优先次序,即最喜欢某人,其次喜欢某人...输出一个稳定婚配方案.所谓稳定,就是指未结婚的一对异性,彼此喜欢对方的程度都胜过自己的另一半,那么这 ...
- JDK,JRE,JVM区别与联系-理解与概括
我们利用JDK(调用JAVA API)开发了属于我们自己的JAVA程序后,通过JDK中的编译程序(javac)将我们的文本java文件编译成JAVA字节码,在JRE上运行这些JAVA字节码,JVM解析 ...
- ecshop 优化_将商品详情页goods.php重命名为shangpin.php
有人说,将商品详情页的文件名 goods.php 改一个名字,对百度收录会有帮助,也许吧,这里不讨论是否有帮助,这里只讲解如何重命名. 例如:我们将 goods.php 改为 shangpin.php ...
- 深入理解ob_flush/flush
ob_flush/flush在手册中的描述, 都是刷新输出缓冲区, 并且还需要配套使用, 所以会导致很多人迷惑… 其实, 他们俩的操作对象不同, 有些情况下, flush根本不做什么事情.. ob_* ...
- 安装rlwrap错误的问题解决方法
You need the GNU readline library(ftp://ftp.gnu.org/gnu/readline/ ) to build this program.如果安装rlwra ...
- T-SQL备忘(4):分页
set statistics io on set statistics time on --SQL Server 2012分页方式 select * from Production.Product o ...
- ArcEngine9.3报错Create output feature class failed
ArcEngine9.3执行IFeatureDataConverter.ConvertFeatureClass Method出错如下错误信息: Create output feature class ...
- 嵌入式 uboot以及kernel添加看门狗临时记录(个人记录未整理乱)
Uboot_Kernerl_Add_Watch_Dog: U-Boot 2010.06 (Nov 01 2013 - 15:28:44) DRAM: 128 MiBCheck spi flash c ...
- 说说shell脚本中的export 和 source,bash
小弟刚刚接触linux,对linux上的很多东西都比较陌生,所以写一写博客,当做自己工作的总结和技术的积累吧,也是鞭策自己不断努力的去学习. 今天之所以起这个标题,把export,source ,ba ...