https://codeforces.com/problemset/problem/842/D
给你个数组让你求mex(不存在的最小数字),每次异或个x,然后重新求mex。
把数组中不存在的数字放入字典树就行了。
每次摸着0往下走,除非x的那一位是1.最后的答案异或一下 x,因为刚刚从1摸下来其实相当于转了一圈。。。。
具体看图和代码把
#include <iostream> #include <vector> #include <cstring> #include <cstdio> #include <algorithm> #include <set> using namespace std; typedef long long ll; const int maxn = 3e5+111; int n,m; int vis[maxn*3]; int tree[maxn*31][3]; int cnt = 0; int list[maxn*31]; int add(int x){ int root = 0; for(int i=30;i>=0;i--){ int t = (x>>i)&1; if(tree[root][t] == 0) tree[root][t] = ++cnt; root = tree[root][t]; } list[root] = x; return 0; } int find(int cns){ int root = 0; for(int i = 30;i>=0;i--){ int t = (cns>>i)&1; if(tree[root][t] == 0) root = tree[root][t^1]; else root = tree[root][t]; } return list[root]^cns; } int main(){ cin>>n>>m; int x; for(int i=0;i<n;i++){ cin>>x; vis[x] = 1; } for(int i=0;i<600009;i++){ if(vis[i] == 0){ add(i); // cout<<cnt<<endl; } } int ans = 0; // cout<<"ok"<<endl; for(int i=0;i<m;i++){ cin>>x; ans ^= x; cout<<find(ans)<<endl; } return 0; }