Vitya and Strange Lesson(01字典树)

来源:互联网 发布:淘宝买家评价多久清空 编辑:程序博客网 时间:2024/06/05 22:50
Vitya and Strange Lesson
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

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, andm queries. Each query is characterized by one numberx and consists of the following consecutive steps:

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

Note that after each query the array changes.

Input

First line contains two integer numbers n andm (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 numberx (0 ≤ x ≤ 3·105).

Output

For each query print the answer on a separate line.

Examples
Input
2 21 313
Output
10
Input
4 30 1 5 6124
Output
200
Input
5 40 1 5 6 71145
Output
2202题目大意:给出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 0x3f3f3f3fusing 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;}


原创粉丝点击