题目地址
题意:告诉你一个序列,然后给你m个操作,每个操作就是把这个序列异或上x,然后再得出最小的没有在这个序列中出现的数。
思路:因为异或的定义就是转成2进制的形式,每一位相同的为0,不同的为1。这样的话我们就可以把数转化为二进制存入字典树(二叉树,向左为0向右为1)中,异或的话就是把异或的数转成二进制的形式,把该位为1的翻转一下字典树节点的两个子节点就好了。查询的时候就是一直往左找,直到下面的数是满的就转到右子树去找(这个理解不了可以看下我代码结构体部分的注释),最后得到的结果就是最小的数。(注意因为最大的数才为3*10^5所以20层就好了,不会出现超过20层的情况,然后转成二进制以后要在前面补0,这样就比较好在字典树中存值了)
#include <iostream>
#include <cstring>
#include <string>
#include <queue>
#include <vector>
#include <map>
#include <set>
#include <stack>
#include <cmath>
#include <cstdio>
#include <algorithm>
#include <iomanip>
#define N 300010
#define M 2//每个节点的子节点的个数
#define LL __int64
#define inf 0x3f3f3f3f
#define lson l,mid,ans<<1
#define rson mid+1,r,ans<<1|1
#define getMid (l+r)>>1
#define movel ans<<1
#define mover ans<<1|1
using namespace std;
const LL mod = 1000000007;
int n, m;
int num[N];
struct node {
int cnt, res;//cnt存的是它下面有多少个数,就是查询的时候判断这边的数是不是已经完全都有了,res就是记录异或的值,想当与一个延迟标记省时间
node *next[M];
void init() {
for (int i = 0; i < M; i++) {
next[i] = NULL;
}
res = 0;
cnt = 0;
}
};
void push_down(node *p, int d) {//异或时反转左右孩子,向下传递
for (int i = 0; i < M; i++) {
if (p->next[i]) {
p->next[i]->res ^= p->res;
}
}
if ((p->res >> d) & 1) {
swap(p->next[0], p->next[1]);
}
p->res = 0;
}
struct Trie {
void insert(node *root, int num) {//需要自定义
node *p = root;
p->cnt++;
for (int i = 20; ~i; i--) {
int k = (num >> i) & 1;
if (p->next[k] == NULL) {
p->next[k] = new node;
p->next[k]->init();
}
p = p->next[k];
p->cnt++;
}
}
int solve(node *root) {
node *p = root;
int ans = 0;
for (int i = 20; ~i; i--) {
push_down(p, i);
if (p->next[0] == NULL || (p->next[0] != NULL&&p->next[0]->cnt != (1 << i))) {
p = p->next[0];
}
else {
p = p->next[1];
ans += 1 << i;
}
if (p == NULL) return ans;
}
}
void Free(node *p) {
for (int i = 0; i < M; i++)if (p->next[i]) Free(p->next[i]);
delete p;
}
}tree;
int main() {
cin.sync_with_stdio(false);
node *root;
while (cin >> n >> m) {
for (int i = 0; i < n; i++) {
cin >> num[i];
}
sort(num, num + n);
n = unique(num, num + n) - num;
root = new node;
root->init();
for (int i = 0; i < n; i++) {
tree.insert(root, num[i]);
}
for (int i = 0; i < m; i++) {
int k;
cin >> k;
root->res ^= k;
cout << tree.solve(root) << endl;
}
tree.Free(root);
}
return 0;
}