G - Vitya and Strange Lesson 字典树 数组模拟

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

给出一个数组,每次操作将整个数组亦或一个数x,问得到的数组的结果中的mex.mex表示为自然数中第一个没有出现过的数。

  思路:将其余数字插入字典树里,然后异或得到的最小值就是所需要的值

  x^a^b=x^(a^b).

#include <iostream>
#include <stdio.h>
#include <string.h>
#include<algorithm>
using namespace std;
int a[600005];
int tree[20*600005][2];
int tot;int val[20*600005];
void init()
{
    memset(tree,0,sizeof(tree));
    memset(val,0,sizeof(val));
    tot=0;
}
void insert(int x)
{
    int p=0;
    for(int i=31;i>=0;i--)
    {
        int t=(x>>i)&1;
        if(!tree[p][t])
            tree[p][t]=++tot;
        p=tree[p][t];
    }
    val[p]=x;
}
int Find(int x)
{
    int p=0;
    for(int i=31;i>=0;i--)
    {
        int t=(x>>i)&1;
        if(tree[p][t])
            p=tree[p][t];
        else
            p=tree[p][t^1];
    }
    return val[p];
}
int main()
{
    int n,m,k;
    scanf("%d%d",&n,&m);
    memset(a,0,sizeof(a));
    for(int i=0;i<n;i++)
    {
        scanf("%d",&k);
        a[k]=1;
    }
    init();
   // printf("&&\n");
    for(int i=0;i<600001;++i)
    {
        if(!a[i])
        insert(i);
    }
    //printf("***\n");
    int rt=0;
    for(int i=0;i<m;i++)
    {
        scanf("%d",&k);
        rt^=k;
        k=rt^Find(rt);
        printf("%d\n",k);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/Kuguotao/article/details/83214862
今日推荐