Vitya and Strange Lesson(01字典树)
来源:互联网 发布:淘宝买家评价多久清空 编辑:程序博客网 时间:2024/06/05 22:50
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.
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).
For each query print the answer on a separate line.
2 21 313
10
4 30 1 5 6124
200
5 40 1 5 6 71145
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;}
- Vitya and Strange Lesson(01字典树)
- D、Vitya and Strange Lesson(字典树模版)
- Code Forces 824D Round#430 Div2D:Vitya and Strange Lesson :01字典树
- Codeforces Round #430-01字典树&类异或最大值-D. Vitya and Strange Lesson
- D. Vitya and Strange Lesson
- Codeforces Round #430 (Div. 2) D.Vitya and Strange Lesson 异或 01字典树补集最小
- [Codeforces 842D Vitya and Strange Lesson]异或字典树
- Codeforces 842D Vitya and Strange Lesson【逆向思维+字典树查询亦或最小值】
- 【Codeforces Round #430 (Div. 2) D】 D. Vitya and Strange Lesson ("带lazy" 的字典树)
- CF 842D Vitya and Strange Lesson 01Trie(mex)
- Codeforce#430D.Vitya and Strange Lesson(01Trie)
- Codeforces 842 D Vitya and Strange Lesson 线段树
- Codeforces 842 D. Vitya and Strange Lesson (trie)
- Codeforces 842 D Vitya and Strange Lesson 线段树 (未理解透)
- codeforces 842D. Vitya and Strange Lesson
- Codeforces 842D Vitya and Strange Lesson
- Codeforces 842 D Vitya and Strange Lesson
- CodeForces 842D Vitya and Strange Lesson
- 关于数组(二)
- 分布式基础(一)概述
- 最大二叉搜索子树 后序遍历
- 第八章 拦截器机制(一) 拦截器介绍
- 蜕变的Judy年中总结
- Vitya and Strange Lesson(01字典树)
- 快速排序-java实现
- 初始CSS
- Java中的回车(\r)和换行(\n)
- 【01】vue.js — 简析入门
- Jmeter实现百分比业务比例
- 用Virtual User Generator 录制
- 京东面试题分析
- 命令模式