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.
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).
For each query print the answer on a separate line.
2 2 1 3 1 3
1 0
4 3 0 1 5 6 1 2 4
2 0 0
5 4 0 1 5 6 7 1 1 4 5
2 2 0 2 题目大意:给出n个数,然后给出m次查询,对于每一次查询给出一个数,然后n个数去异或这个数得到一个新的数组,然后找出不在这个数组的最小非负整数。 题目思路:我们知道异或是满足分配律的,所以我们的修改操作是可以达到O(1),为什么呢,因为a^b^c == a^(b^c),所以我们不用去修改原数组的值,只用用一个全局异或 就行了,那么我们怎么去查询呢,对于这道题来说,根据经验,我们可以用字典树去写,把每一个数拆成串去写,但是怎么去具体操作呢,我们知道去找一个最小的,是去找每一位 的的相同值,但是这里有一个限定条件就是要找数组里面没有的,所以我们不能仅仅去找相同值的,我们这里因为要找数组中没有的,所以当相同值的子树是不满的,就说明 我们要找的答案在这个子树里,否则就在另外一棵子树中,当要找的子树不存在时就返回就行了,这里还有一个需要注意的就是判断是不是满的树呢,对于一棵树我们只用记录 他的叶子结点个数就行了,每一次经历这个节点就加一,但是需要注意去重。 ac代码:#include<cstdio> #include<iostream> #include<sstream> #include<cstring> #include<algorithm> #include<vector> #define LL long long #define INF 0x3f3f3f3f using namespace std; const int maxn = 3e5+5; int n,m; int a[maxn]; struct node { int nxt[2]; void init(){ memset(nxt,-1,sizeof(nxt)); } }E[maxn*20]; int sz[maxn*20]; int cnt; void add(int x) { int now = 0; sz[now]++; for(int i = 20;i>=0;i--){ int tmp = (x>>i)&1; if(E[now].nxt[tmp]==-1){ E[++cnt].init(); E[now].nxt[tmp] = cnt; } now = E[now].nxt[tmp]; sz[now]++; } if(sz[now]>1){ now = 0; sz[now]--; for(int i = 20;i>=0;i--){ int tmp = (x>>i)&1; now = E[now].nxt[tmp]; sz[now]--; } } } int query(int x) { int now = 0; int res = 0; for(int i = 20;i>=0;i--){ int tmp = (x>>i)&1; if(E[now].nxt[tmp]==!-1) return res; else{ if(sz[E[now].nxt[tmp]]<(1<<i)) now = E[now].nxt[tmp]; else{ res |= (1<<i); if(E[now].nxt[!tmp]==-1) return res; now = E[now].nxt[!tmp]; } } } return res; } int main() { while(~scanf("%d%d",&n,&m)) { cnt = 0; memset(sz,0,sizeof(sz)); E[0].init(); for(int i = 0;i<n;i++){ int x; scanf("%d",&x); add(x); } int now = 0; while(m--){ int x; scanf("%d",&x); now ^= x; printf("%d\n",query(now)); } } return 0; }