Vitya and Strange Lesson (01字典树)
Vitya and Strange Lesson
https://ac.nowcoder.com/acm/problem/112209
题意:给定一组数,然后对所有的数进行异或操作m次异或操作,问你每次操作后,没有出现过的最小的非负整数
题解:
首先需要一个性质(a^b)^c=a^(b^c);
所以我们没有必要对于所有的数进行异或操作。
我们只需要设一个ans=0,每次用输入进来的数于ans进行异或即可。
其次,我们把没有出现过的数字加入进字典树,这样的话我们从高位到低位寻找与当前ans按位 比较相同的数字,如果不相同那么我们就给 返回值加上当前位的值。最后返回值极为最小mex。
/*Keep on going Never give up*/ //#pragma GCC optimize(3,"Ofast","inline") #include<bits/stdc++.h> //#define int long long #define endl '\n' #define Accepted 0 #define AK main() #define I_can signed using namespace std; const int maxn =1e7+10; const int MaxN = 0x3f3f3f3f; const int MinN = 0xc0c0c00c; typedef long long ll; const int inf=0x3f3f3f3f; const ll mod=1e9+7; using namespace std; int trie[maxn][2]; bool visited[maxn]; int cnt; void ins(int x){ int node=0; for(int i=21;i>=0;i--){ int t=(x>>i)&1; if(!trie[node][t]) trie[node][t]=++cnt; node=trie[node][t]; } return ; } int ifind(int x){ int res=0,node=0; for(int i=21;i>=0;i--){ int t=(x>>i)&1; if(trie[node][t]) node=trie[node][t]; else{ res|=1<<i; node=trie[node][t^1]; } } return res; } signed main() { //ios::sync_with_stdio(false); int n,m; cin>>n>>m; memset(visited,false,sizeof visited); for(int i=0;i<n;i++){ int x; cin>>x; visited[x]=true; } int ans=0; for(int i=0;i<600010;i++){ if(!visited[i]){ ins(i); } } for(int i=0;i<m;i++){ int x; cin>>x; ans^=x; cout<<ifind(ans)<<endl; } return 0; }