0
点赞
收藏
分享

微信扫一扫

CF842D Vitya and Strange Lesson

耶也夜 2022-10-25 阅读 155


题目链接:​​传送门​​ 给出一个序列,m次操作每次给出一个数x,让序列中的所有数都异或上x,求每次操作完后的序列mex(最小未出现自然数)

会01trie就简单了
把序列去重后加到01trie中
统计每个子树下有多少个数
查询时左儿子满了就往右走,右儿子同理
直到走到空节点就直接返回
一定注意一开始存一个根节点
也就是cnt一开始一定为1

/**
* @Date: 2019-04-13T10:54:44+08:00
* @Last modified time: 2019-04-13T14:16:27+08:00
*/
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <complex>
#include <algorithm>
#include <climits>
#include <queue>
#include <map>
#include <set>
#include <vector>
#include <iomanip>
#define
#define

using namespace std;
typedef long long ll;
int siz[A], ch[A][2], n, m, a[A], b, s, cnt = 1;
void insert(int x, int fr = 1) {
for (int i = 20; i > 0; i--) {
siz[fr]++;
if (x & (1 << (i - 1))) {
if (!ch[fr][1]) ch[fr][1] = ++cnt;
fr = ch[fr][1];
}
else {
if (!ch[fr][0]) ch[fr][0] = ++cnt;
fr = ch[fr][0];
}
}
siz[fr]++;
}
int ask(int fr = 1, int ans = 0) {
for (int i = 20; i > 0; i--)
if (s & (1 << (i - 1))) {
if (!ch[fr][1]) return ans;
else if (siz[ch[fr][1]] < (1 << (i - 1))) fr = ch[fr][1];
else fr = ch[fr][0], ans += (1 << (i - 1))
}
else {
if (!ch[fr][0]) return ans;
else if (siz[ch[fr][0]] < (1 << (i - 1))) fr = ch[fr][0];
else fr = ch[fr][1], ans += (1 << (i - 1));
}
return ans;
}

int main(int argc, char const *argv[]) {
cin >> n >> m;
for (int i = 1; i <= n; i++) cin >> a[i];
sort(a + 1, a + n + 1);
n = unique(a + 1, a + n + 1) - a - 1;
for (int i = 1; i <= n; i++) insert(a[i]);
while (m--) {
cin >> b; s ^= b;
cout << ask() << endl;
}
return 0;
}


举报

相关推荐

CF:1632C. Strange Test(思维)

CF1132D Stressful Training

D-CF29A Spit Problem

CF1117D Magic Gems

[CF936D]World of Tank

0 条评论