分析
首先,由于异或满足结合律
所以我们可以把每次需要异或的值异或起来
在原01Trie
树上找即可
接下来,我们看一下如何找
由于我们需要的是最小的
所以我们每次走到一个节点的时候
不能走,当且仅当这颗子树是满的
所以我们可以依据这个性质走即可
时间复杂度:
代码
//CF842D #include <algorithm> #include <iostream> #include <cstring> #include <cstdio> #include <cmath> #define Cl(X,Y) memset((X),(Y),sizeof(X)) #define FOR(i,A,B) for(int i=A;i<=B;i++) #define BOR(i,A,B) for(int i=A;i>=B;i--) #define Debug(X) cerr<<#X<<" = "<<X<<" " #define Lowbit(X) (X & (-X)) #define Skip cout<<endl; #define INF 0x3f3f3f3f #define Mod 998244353 #define Rson (X<<1|1) #define Lson (X<<1) using namespace std; typedef long long ll; const int N = 3e5+5; vector<int>a; int son[N*20][2], sz[N*20], cnt, root; inline int newnode() { return ++cnt; } inline void init() { cnt = 0; root = newnode(); } inline void insert(int x) { int p = root; for(int i = 19; i >= 0; --i) { if(x&(1<<i)) { if(son[p][1] == 0) son[p][1] = newnode(); p = son[p][1]; sz[p]++; } else { if(son[p][0] == 0) son[p][0] = newnode(); p = son[p][0]; sz[p]++; } } } int p2[25]; int query(int x) { int p = root, res = 0; for(int i = 19; i >= 0; --i) { if(x&(1<<i)) { if(sz[son[p][1]] != p2[i]) { p = son[p][1]; res |= (1<<i); } else { p = son[p][0]; } } else { if(sz[son[p][0]] != p2[i]) { p = son[p][0]; } else { res |= (1<<i); p = son[p][1]; } } } return res^x; } int main() { p2[0] = 1; FOR(i,1,24) p2[i] = p2[i-1]*2; int n, m; scanf("%d %d", &n, &m); FOR(i,1,n) { int x; scanf("%d", &x); a.emplace_back(x); } sort(a.begin(), a.end()); a.erase(unique(a.begin(), a.end()), a.end()); for(int x : a) { insert(x); } int now = 0; FOR(i,1,m) { int x; scanf("%d", &x); now ^= x; printf("%d\n", query(now)); } return 0; }