codeforces 842D Vitya and Strange Lesson
题目大意:
定义mex数为数组中第一个没有出现的非负整数.有m个操作,每个操作有一个x,将数组中所有的元素都异或x,然后询问当前的mex
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
2
0
0
Input
5 4
0 1 5 6 7
1
1
4
5
Output
2
2
0
2
%%%%yzh大佬,学会了新姿势:http://www.cnblogs.com/Yuzao/default.html?page=1
这题正解其实是01Trie
按照理解,Trie用来保存字符串,但也可以通过01分支来保存数
这样我们只要找到树中最靠左的空节点,对应的值即为答案
更新可以用lazy标记,如果有标记,则反转左右子节点
如果左边有空节点,那么就返回向左查找的值
没有则返回右节点查找的值+2^(dep-1)[左节点数量]
然后注意本题是按高位向低位拓展,因为高位分支少,所以会更快
YZD&&HJW&&SAC&&YZH%%%orz大佬
1 #include<iostream> 2 #include<cstdio> 3 #include<algorithm> 4 #include<cstring> 5 using namespace std; 6 struct Node 7 { 8 int l,r; 9 }c[1200001]; 10 int seg[1200001],rev[1200001],root,tot,n,m; 11 void insert(int &rt,int x,int dep) 12 { 13 if (!rt) rt=++tot; 14 if (dep==0) 15 { 16 seg[rt]=1; 17 return; 18 } 19 if (x&(1<<dep-1)) insert(c[rt].r,x,dep-1); 20 else insert(c[rt].l,x,dep-1); 21 seg[rt]=seg[c[rt].l]&&seg[c[rt].r]; 22 } 23 void pushdown(int &rt,int dep) 24 { 25 if (rev[rt]==0) return; 26 int k=rev[rt]; 27 rev[c[rt].l]^=k; 28 rev[c[rt].r]^=k; 29 if (k&(1<<dep-1)) 30 swap(c[rt].l,c[rt].r); 31 rev[rt]=0; 32 } 33 int query(int &rt,int dep) 34 { 35 if (dep==0) return 0; 36 pushdown(rt,dep); 37 if (seg[c[rt].l]==0) return query(c[rt].l,dep-1); 38 else return query(c[rt].r,dep-1)+(1<<dep-1); 39 } 40 int main() 41 {int i,j,x; 42 cin>>n>>m; 43 for (i=1;i<=n;i++) 44 { 45 scanf("%d",&x); 46 insert(root,x,20); 47 } 48 for (i=1;i<=m;i++) 49 { 50 scanf("%d",&x); 51 rev[root]^=x; 52 printf("%d\n",query(root,20)); 53 } 54 }