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:

  1. "+ x" — add integer x to multiset A.
  2. "- 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.
  3. "? 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
  1. 10
  2. + 8
  3. + 9
  4. + 11
  5. + 6
  6. + 1
  7. ? 3
  8. - 8
  9. ? 3
  10. ? 8
  11. ? 11
output
  1. 11
  2. 10
  3. 14
  4. 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 .

【题解】

如果题目没看懂就看一下上面那个note的样例解释嘛。应该知道是什么意思了吧。

然后我把样例的前6个操作数的二进制列举一下。

如果不足4位就前面补0

1000

1001

1011

0110

0001





询问0011

思路是这样的

把前面5个数字加入字典树中。

然后从根节点开始。看到询问的二进制第一位是0.

0的话xor什么最好呢?当然是1.

那就看看从根节点往下有没有一个1有就往下走,没有的话就走0(0是一直存在的。所以肯定可以走);然后二进制的第二位也以此类推。

最后我们走到底的肯定是最大值。

这里涉及到一个原理就是

(二进制)

1000 > 0111

即2^x > 2^(x-1)+2^(x-2) + ...+ 2^0

实际上左边那个等于右边加1.

节点加入和删除的话

给每个节点都设置一个值。走到这个点就增加一下这个节点的值。然后要删除的时候仍旧走一遍这个路。然后递减路上走过的节点的值。

这3个操作其实很像的。

然后10^9 二进制的长度为30

【代码】

  1. #include <cstdio>
  2.  
  3. const int MAX_SIZE = 7000000;
  4.  
  5. int q, v[MAX_SIZE][2] = { 0 }, totn = 0, num[MAX_SIZE] = { 0 };
  6. int a[40];
  7.  
  8. //v[t][0],v[t][1]分别表示t的左右儿子,左儿子代表0
  9.  
  10. void add(int x)
  11. {
  12. int temp = 0, temp1 = x;
  13. a[0] = 30;
  14. while (temp1 > 0) //从后往左加入二进制各个位
  15. {
  16. a[a[0]] = temp1 & 1;
  17. temp1 = temp1 >> 1;
  18. a[0]--;
  19. }
  20. for (int i = 1; i <= a[0]; i++)//1..a[0]是补0
  21. {
  22. if (v[temp][0] == 0)
  23. v[temp][0] = ++totn;
  24. temp = v[temp][0];
  25. num[temp]++;
  26. }
  27. for (int i = a[0] + 1; i <= 30; i++)//a[0]+1..30才是这个数的二进制
  28. {
  29. if (v[temp][a[i]] == 0)
  30. v[temp][a[i]] = ++totn;
  31. temp = v[temp][a[i]];
  32. num[temp]++;
  33. }
  34. }
  35.  
  36. void de_lete(int x)
  37. {
  38. int temp = 0, temp1 = x;
  39. a[0] = 30;
  40. while (temp1 > 0)
  41. {
  42. a[a[0]] = temp1 & 1;
  43. temp1 = temp1 >> 1;
  44. a[0]--;
  45. }
  46. for (int i = 1; i <= a[0]; i++)
  47. {
  48. temp = v[temp][0];
  49. num[temp]--;
  50. }
  51. for (int i = a[0] + 1; i <= 30; i++)
  52. {
  53. temp = v[temp][a[i]];
  54. num[temp]--;
  55. }
  56. }
  57.  
  58. int query(int x)
  59. {
  60. int temp = 0, temp1 = x;
  61. a[0] = 30;
  62. while (temp1 > 0)
  63. {
  64. a[a[0]] = temp1 & 1;
  65. temp1 = temp1 >> 1;
  66. a[0]--;
  67. }
  68. int leijia = 0;
  69. for (int i = 1; i <= a[0]; i++)
  70. if (v[temp][1] != -1 && num[v[temp][1]] > 0)
  71. {
  72. temp = v[temp][1];
  73. leijia += 1 << (30 - i); //代表2^(30-i)
  74. }
  75. else
  76. temp = v[temp][0];
  77. for (int i = a[0] + 1; i <= 30; i++)
  78. if (v[temp][1 - a[i]] != -1 && num[v[temp][1 - a[i]]] > 0)
  79. {
  80. temp = v[temp][1 - a[i]];
  81. leijia += 1 << (30 - i);
  82. }
  83. else
  84. temp = v[temp][a[i]];
  85. return leijia;
  86. }
  87.  
  88. void input_data()
  89. {
  90. scanf("%d", &q);
  91. for (int i = 1; i <= q; i++)
  92. {
  93. char op[5];
  94. int x;
  95. scanf("%s%d", op, &x);
  96. if (op[0] == '+')
  97. add(x);
  98. else
  99. if (op[0] == '-')
  100. de_lete(x);
  101. else
  102. printf("%d\n", query(x));
  103. }
  104. }
  105.  
  106. int main()
  107. {
  108. //freopen("F:\\rush.txt", "r", stdin);
  109. add(0);
  110. input_data();
  111. return 0;
  112. }

【35.20%】【CF 706D】Vasiliy's Multiset的更多相关文章

  1. codeforces 706D D. Vasiliy's Multiset(trie树)

    题目链接: D. Vasiliy's Multiset time limit per test 4 seconds memory limit per test 256 megabytes input ...

  2. 【codeforces】【比赛题解】#851 CF Round #432 (Div.2)

    cf真的难…… 点我浏览丧题. [A]Arpa和她对墨西哥人浪的研究 Arpa正在对墨西哥人浪进行研究. 有n个人站成一排,从1到n编号,他们从时刻0开始墨西哥人浪. 在时刻1,第一个人站起来.在时刻 ...

  3. JAVA 基础编程练习题20 【程序 20 求前 20 项之和】

    20 [程序 20 求前 20 项之和] 题目:有一分数序列:2/1,3/2,5/3,8/5,13/8,21/13...求出这个数列的前 20 项之和. 程序分析:请抓住分子与分母的变化规律. pac ...

  4. 【字典树】【贪心】Codeforces 706D Vasiliy's Multiset

    题目链接: http://codeforces.com/contest/706/problem/D 题目大意: 三种操作,1.添加一个数,2.删除一个数,3.查询现有数中与x异或最大值.(可重复) 题 ...

  5. 【CF 453A】 A. Little Pony and Expected Maximum(期望、快速幂)

    A. Little Pony and Expected Maximum time limit per test 1 second memory limit per test 256 megabytes ...

  6. 【实战Java高并发程序设计6】挑战无锁算法:无锁的Vector实现

    [实战Java高并发程序设计 1]Java中的指针:Unsafe类 [实战Java高并发程序设计 2]无锁的对象引用:AtomicReference [实战Java高并发程序设计 3]带有时间戳的对象 ...

  7. 【实战Java高并发程序设计 3】带有时间戳的对象引用:AtomicStampedReference

    [实战Java高并发程序设计 1]Java中的指针:Unsafe类 [实战Java高并发程序设计 2]无锁的对象引用:AtomicReference AtomicReference无法解决上述问题的根 ...

  8. 【Android】【录音】Android录音--AudioRecord、MediaRecorder

    [Android][录音]Android录音--AudioRecord.MediaRecorder Android提供了两个API用于实现录音功能:android.media.AudioRecord. ...

  9. 【转】从外行的视角尝试讲解为什么这回丰田栽了【全文完】【v1.01】

    转自:http://club.tgfcer.com/thread-6817371-1-1.html  [第一部分]背景简介 前几年闹得沸沸扬扬的丰田刹不住事件最近又有新进展.十月底俄克拉荷马的一次庭审 ...

随机推荐

  1. Vue Invalid handler for event "": got undefined

    原因:绑定的方法不是放在methods:{}里.比如我把绑定的函数写在了computed:{}里就会报这个错.

  2. 解决ListCtrl控件第一列文字不能居中显示的问题/修改网格线

    把CListCtrl设置为Report风格,但是插入第一列的时候(InsertColumn)的时候会发现文字不能居中.即使使用了LVCFMT_CENTER,其他列都可以正常居中,但第一列仍然靠左显示. ...

  3. 【AIM Tech Round 4 (Div. 2) B】Rectangles

    [链接]http://codeforces.com/contest/844/problem/B [题意] 也是道计数水题,没什么记录意义 [题解] 枚举每个点的位置在,然后往右往下 枚举和它一样颜色的 ...

  4. Objc执行时读取和写入plist文件遇到的问题

    以下是本猫保持游戏NPC和物件交互的plist文件: 随着游戏和玩家逐步发生互动,玩家会改动人物和物件的交互的状态.这也是RPG游戏最主要的功能. 在切换每一个地图时须要将上一个地图发生的改变存储到p ...

  5. bootstrap课程9 bootstrap如何实现动画加载进度条的效果

    bootstrap课程9 bootstrap如何实现动画加载进度条的效果 一.总结 一句话总结:在bootstrap进度条的基础上添加js(定时器),动态的改变进度条即可.很简单的. 1.路径导航是什 ...

  6. JS实现拖拽小案例

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  7. Thinkphp5创建控制器

    今天我们就来创建一个控制器: <?php namespace app\index\controller; use think\Controller; class Test extends Con ...

  8. poj 1191 棋盘切割 (压缩dp+记忆化搜索)

    一,题意: 中文题 二.分析: 主要利用压缩dp与记忆化搜索思想 三,代码: #include <iostream> #include <stdio.h> #include & ...

  9. js进阶 14-5 $.getScript()和$.getJSON()方法的作用是什么

    js进阶 14-5 $.getScript()和$.getJSON()方法的作用是什么 一.总结 一句话总结:$.getScript()和$.getJSON()方法专门用来加载JS/JSON文件(远程 ...

  10. 《你不知道的JavaScript(上)》笔记——提升

    笔记摘自:<你不知道的JavaScript(上)>第3章 提升 1.包括变量和函数在内的所有声明都会在任何代码被执行前首先被处理. 2.变量和函数声明从它们在代码中出现的位置被“移动”到了 ...