题意:

Today at the lesson Vitya learned a very interesting function — mex. Mex of a sequence of numbers is the minimum non-negative number that is not present in the sequence as element. For example, mex([4, 33, 0, 1, 1, 5]) = 2 and mex([1, 2, 3]) = 0.

Vitya quickly understood all tasks of the teacher, but can you do the same?

You are given an array consisting of n non-negative integers, and m queries. Each query is characterized by one number x and consists of the following consecutive steps:

  • Perform the bitwise addition operation modulo 2 (xor) of each array element with the number x.
  • Find mex of the resulting array.

Note that after each query the array changes.

Input

First line contains two integer numbers n and m (1 ≤ n, m ≤ 3·105) — number of elements in array and number of queries.

Next line contains n integer numbers ai (0 ≤ ai ≤ 3·105) — elements of then array.

Each of next m lines contains query — one integer number x (0 ≤ x ≤ 3·105).

Output

For each query print the answer on a separate line.

Examples

Input
2 2
1 3
1
3
Output
1
0
Input
4 3
0 1 5 6
1
2
4
Output
2
0
0
Input
5 4
0 1 5 6 7
1
1
4
5
Output
2
2
0
2

题意:

找出来这n个数中没有的最小自然数

之后有m次对数组的处理(设m行每行输入的数为x),让数组里面的所有数都和x异或。然后输出这n个数中没有的最小自然数

注释+代码:

 1 /*
2 将所有的数字以二进制的方式插入到 trie 树中,然后我们便可以很方便的求出一个序列的 mex 值。
3 假如要全局异或一个数 x ,且 x 的二进制从高到低第 i 位是 1 ,则 trie 树中的第 i 层所有节点都要翻转左右孩子。
4
5 为什么遇到1要翻转,遇到0不需要?
6 如果是0的话,那么原来数是0,异或之后结果还是0;如果原来数是1,异或之后结果还是1
7
8 并且x^y^z=x^(y^z)
9 */
10 #include <iostream>
11 #include <cstdio>
12 #include <cstring>
13 #include <cstdlib>
14 #include <algorithm>
15 using namespace std;
16 typedef long long ll;
17 const int maxn=20;
18 const int mod=998244353;
19 const int N=3e5+10;
20 typedef struct Trie* TrieNode;
21 int v[N];
22 struct Trie
23 {
24 int val,sum;
25 TrieNode next[2];
26 Trie()
27 {
28 val=0;
29 sum=0;
30 memset(next,NULL,sizeof(next));
31 }
32 };
33 void inserts(TrieNode root,int x)
34 {
35 TrieNode p = root;
36 for(int i=maxn;i>=0;--i)
37 {
38 int temp=(x>>i)&1;
39 if(p->next[temp]==NULL) p->next[temp]=new struct Trie();//printf("*%d*",temp);
40 //p->next[temp]->sum+=1;
41 p=p->next[temp];
42 p->sum+=1;
43 }
44 }
45 void update(TrieNode p,int x)
46 {
47 for(int i=0;i<2;++i)
48 if(p->next[i]!=NULL)
49 p->next[i]->val^=p->val; //这个p->next[i]->val为什么要异或?
50 if((p->val>>x)&1) //因为我们每一次只能走字典树的一个方向,所以另一个方向是没有异或过这个x的,所以报
51 swap(p->next[0],p->next[1]); //保留下来,和线段树的懒惰标记差不多
52 p->val=0;
53 }
54 void query(TrieNode root,int x)
55 {
56 int ans=0;
57 TrieNode p=root;
58 for(int i=maxn;i>=0;i--)
59 {
60 update(p,i);
61 if(p->next[0]==NULL || p->next[0]->sum!=(1<<i)) //(1<<i)代表另一个树枝上所有数都存在时的个数
62 p=p->next[0]; //因为咱们时从二进制数的高位枚举到低位,所以遇到能走的零就要走
63 else p=p->next[1],ans|=1<<i;
64 if(p==NULL) break;
65 }
66 printf("%d\n",ans);
67 }
68 void Del(TrieNode root)
69 {
70 for(ll i=0 ; i<2 ; ++i)
71 {
72 if(root->next[i])Del(root->next[i]);
73 }
74 delete(root);
75 }
76 int main()
77 {
78 int n,m;
79 scanf("%d%d",&n,&m);
80 for(int i=0;i<n;++i)
81 scanf("%d",&v[i]);
82 sort(v,v+n);
83 TrieNode root=new struct Trie();
84 inserts(root,v[0]);
85 for(int i=1;i<n;++i)
86 {
87 if(v[i]!=v[i-1])
88 inserts(root,v[i]);
89 }
90 while(m--)
91 {
92 int x;
93 scanf("%d",&x);
94 root->val=x; //每一次都要
95 query(root,x);
96 }
97 Del(root);
98 return 0;
99 }

Vitya and Strange Lesson CodeForces - 842D 字典树+交换节点的更多相关文章

  1. 【cf842D】Vitya and Strange Lesson(01字典树)

    D. Vitya and Strange Lesson 题意 数列里有n个数,m次操作,每次给x,让n个数都异或上x.并输出数列的mex值. 题解 01字典树保存每个节点下面有几个数,然后当前总异或的 ...

  2. codeforces 842 D. Vitya and Strange Lesson(01字典树+思维+贪心)

    题目链接:http://codeforces.com/contest/842/problem/D 题解:像这种求一段异或什么的都可以考虑用字典树而且mex显然可以利用贪心+01字典树,和线段树差不多就 ...

  3. D. Vitya and Strange Lesson Codeforces Round #430 (Div. 2)

    http://codeforces.com/contest/842/problem/D 树 二进制(路径,每个节点代表一位) #include <cstdio> #include < ...

  4. Codeforces Round #430 (Div. 2) Vitya and Strange Lesson

    D.Vitya and Strange Lesson(字典树) 题意: 给一个长度为\(n\)的非负整数序列,\(m\)次操作,每次先全局异或\(x\),再查询\(mex\) \(1<=n< ...

  5. CodeForeces 842d Vitya and Strange Lesson ——(带lazy标记的01字典树)

    给一个序列,每次操作对这个序列中的所有数异或一个x,问每次操作完以后整个序列的mex值. 做法是去重后构建01字典树,异或x就是对root加一个x的lazy标志,每次pushDown时如果lazy的这 ...

  6. Codeforces Round #430 (Div. 2) D. Vitya and Strange Lesson

    因为抑或,一眼字典树 但是处理起来比较难 #include<iostream> #include<map> #include<iostream> #include& ...

  7. 【Codeforces Round #430 (Div. 2) D】Vitya and Strange Lesson

    [链接]点击打开链接 [题意] 给出一个数组,每次操作将整个数组亦或一个数x,问得到的数组的结果中的mex.mex表示为自然数中第一个没有出现过的数. [题解] 异或的效果是可以累加的,所以不用每次都 ...

  8. E - Petya and Exam CodeForces - 832B 字典树+搜索

    E - Petya and Exam CodeForces - 832B 这个题目其实可以不用字典树写,但是因为之前写过poj的一个题目,意思和这个差不多,所以就用字典树写了一遍. 代码还是很好理解的 ...

  9. Watto and Mechanism CodeForces - 514C (字典树,哈希)

    大意: 给定字符串集$S$, 每次询问给出字符串$a$, 求$S$中是否存在一个字符串恰好与$a$相差一个字符. 直接建字典树暴力复杂度是$O(n\sqrt{n})$, 也可以用set维护所有哈希值, ...

随机推荐

  1. 数学建模学习笔记 | matlab基本命令及用法

    前言 数学建模对matlab水平的要求 了解matlab的基本用法,如常用命令.脚本结构.矩阵的基本操作.绘图等: 熟悉matlab的程序结构,能创建和引用函数: 熟悉常见模型的求解算法和套路: 自主 ...

  2. linux最大打开文件句柄数

    linux最大打开文件句柄数,即打开文件数最大限制,就是规定的单个进程能够打开的最大文件句柄数量(Socket连接也算在里面,默认大小1024) liunx中文件句柄有两个限制,一种是用户级的,一种是 ...

  3. char什么时候会用空格进行填充?

    char什么时候会用空格进行填充?

  4. 【Git】5、Git如何提交代码到远程仓库

    提交代码:如何把修改后的代码提交到远程仓库 文章目录 提交代码:如何把修改后的代码提交到远程仓库 1.同步远程代码 2.检查改动文件 3.添加文件到缓存 4.提交代码 5.推送代码 6.我的整个流程 ...

  5. Mybatis 一级缓存和二级缓存的使用

    目录 Mybatis缓存 一级缓存 二级缓存 缓存原理 Mybatis缓存 官方文档:https://mybatis.org/mybatis-3/zh/sqlmap-xml.html#cache My ...

  6. DG主备切换遇到not allwod或者RESOLVABLE GAP解决办法

    今天做switchover,环境是11.2.0.3+OEL5.7,开始时主备库状态都是正常的,符合直接切换条件: 主库: SQL> select open_mode,database_role, ...

  7. 缓存淘汰算法 LRU 和 LFU

    LRU (Least Recently Used), 即最近最少使用用算法,是一种常见的 Cache 页面置换算法,有利于提高 Cache 命中率. LRU 的算法思想:对于每个页面,记录该页面自上一 ...

  8. Gradle使用及配置

    构建工具:Gradle(6.8) 下载地址:https://gradle.org/releases/ 下载最新版的二进制文件即可,下载"gradle-6.8.1-bin.zip文件,下载后完 ...

  9. Linux下利用ifconfig命令查看和操纵网络接口

    为了说明这个问题,首先我们需要解释一下在Linux系统下"网络接口"的含义.通俗来讲,Linux中的所谓网络接口就是指本机的网卡,它相当于计算机的一台负责对网络进行收发数据的外设. ...

  10. inode占满导致No space left on device inode快速解决方法

    暂未发现其他比我这个更快的方法. 因为其他方法会展示那个非常卡的目录,导致效率极低.而我这个方法不会去展示那个目录. 查找占用的目录 find / -type d -size +1M -maxdept ...