Codeforces 842 D 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.
题意:给你一段数字,有q个操作,每次对整段数字全部元素进行xor
并输出当前这段数字的mex的值
心得:一开始没有想明白要用字典树,当前想到一个做法就是假设是
每次操作只改变一个数字的值,那就可以用树状数组做,单点修改,
然后二分找第一个满足i<sum[i]即可,可惜是修改一整串。
搜了题解看到01字典树突然有点明白了,假设答案的范围是xxxxxx=ans
(6位二进制内),那么一定存在一个数sco,使得 sco xor num=ans,
此时sco也是在6位二进制内。从0到(ans-1)每个数都不是答案,说明这
些值xor上num应该会出现在原数组上,而ans必然不会出现。所以在答案
在6位数字的情况下,我们只需要把这些原数组上的值去掉即可。然后在剩
下的数当中,寻找与num xor的最小值即可,同理,这个题目数据二进制
在20位的情况下就可以成立了。
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<vector>
#include<map>
#define IOS ios::sync_with_stdio(0),cin.tie(0)
#define sf(a) scanf("%d",&a)
#define dg(a) cout<<"#a"<<" "<<a<<endl
#define pi acos(double(-1))
const int mod=1e9+7;
using namespace std;
const int N=6e6+10;
typedef long long ll;
int l[N],r[N];
int id;
bool tags[N];
void inst(int num)
{
int cur=0;
for(int i=19;i>=0;i--)
{
int bits=(1<<i)#
if(bits)
{
if(!r[cur])
{
r[cur]=++id;
}
cur=r[cur];
}
else
{
if(!l[cur])
{
l[cur]=++id;
}
cur=l[cur];
}
}
}
int findmin(int num)
{
int cur=0;
int ans=0;
for(int i=19;i>=0;i--)
{
int bits=(1<<i)#
if(bits)
{
if(r[cur])
{
cur=r[cur];
}
else
{
ans+=(1<<i);
cur=l[cur];
}
}
else
{
if(l[cur])
{
cur=l[cur];
}
else
{
ans+=(1<<i);
cur=r[cur];
}
}
}
return ans;
}
int main()
{
IOS;
int n,m;
cin>>n>>m;
for(int i=1;i<=n;i++)
{
int num;
cin>>num;
tags[num]=true;
}
for(int i=0;i<=(1<<19);i++)
{
if(!tags[i])
{
inst(i);
}
}
int cur=0;
while(m--)
{
int num;
cin>>num;
cur^=num;
cout<<findmin(cur)<<endl;
}
return 0;
}