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
题意:告诉你一个序列,然后给你m个操作,每个操作就是把这个序列异或上x,然后再得出最小的没有在这个序列中出现的数。就是所谓的mex;
解题思路:题目让找出没有出现的数的最小值,那就把没有出现的数存到插入到字典树中,(因为每个数异或一个数得到的结果是不同的,所以把出现的数异或后找没出现的数的最小值,就相当于 把没出现的数异或后得到的最小值是一样的),所以就把没出现的数存入字典树,每次找异或后得到的值最小;注意这道题的数据范围(代码中有解释);
具体看代码:
#include<cstdio>
#include<cstring>
#include<string>
#include<stdlib.h>
#include<iostream>
#include<algorithm>
#include<queue>
#include<math.h>
#include<map>
#include<vector>
#include<stack>
#define inf 0x3f3f3f3f
using namespace std;
typedef __int64 ll;
const int N=2;
const int M=1010005;//标记数组开的空间
const int MA=20;
//这里要解释一下M为啥比30W大,虽然题目只是说最大3*10^5,转换成二进制后有20位,
//如果二十位全为1就有2^20-2,大约100W,所以对应的,标记数组应该开到101W,但是这道题开到60W就能AC
typedef struct Node
{
int count;
Node *Next[N];
int val;
} Node;
Node * build()
{
Node *node=(Node *)malloc(sizeof(Node));
node->count=0;
node->Next[0]=node->Next[1]=0;
return node;
}
void change(int x,int a[])
{
for(int i=0; i<MA; i++)
a[i]=(x>>(MA-1-i))&1;
}
void tire_insert(Node *root,int a[],int t)
{
Node *p=root;
int i=0;
for(i=0;i<MA;i++)
{
if(p->Next[a[i]]==NULL)
p->Next[a[i]]=build();
p=p->Next[a[i]];
p->count++;
if(i==MA-1)
p->val=t;
}
}
int found(Node *root,int a[])
{
int i,ans=0;
Node *p=root;
for(i=0;i<MA;i++)
{
if(p->Next[a[i]]!=NULL)
p=p->Next[a[i]];
else
p=p->Next[!a[i]];
}
return p->val;
}
int main()
{
int n,m,mp[M];//把出现的数用mp标记
while(~scanf("%d %d",&n,&m))
{
int a[MA],i,j,tmp,c;
Node *root=build();
memset(mp,0,sizeof(mp));
for(i=0;i<n;i++)
{
scanf("%d",&tmp);
mp[tmp]=1;
}
for(i=0;i<=M;i++)
{
if(mp[i]==0)
{
change(i,a);
tire_insert(root,a,i);
}
}
tmp=0;
for(i=0;i<m;i++)
{
scanf("%d",&c);
tmp^=c;
change(tmp,a);
printf("%d\n",found(root,a)^tmp);
}
}
return 0;
}