CF842D Vitya and Strange Lesson
CF842D Vitya and Strange Lesson
Description
mex 是一个序列中没有出现过的最小非负整数。
给出你一个长度为 n 的非负整数序列以及 m 个询问,每次询问先给你一个整数 x ,然后:
- 把序列中所有数异或上 x
- 输出序列的 mex
Solution
题目要求求mex,则只考虑每个数是否出现
于是可以想到建出Trie
考虑修改操作
如果某位异或上的数为0,显然不影响
而异或1,就是交换左右子树
#include<bits/stdc++.h> using namespace std; #define LL long long inline LL read() { LL f = 1,x = 0; char ch; do { ch = getchar(); if(ch == '-')f = -1; }while(ch < '0'||ch > '9'); do { x = (x<<3) + (x<<1) + ch - '0'; ch = getchar(); }while(ch >= '0' && ch <= '9'); return f*x; } const int MAXN = 300000 + 10; map<int,int>used; int n,m; int Trie[MAXN * 21][2]; int tot[MAXN * 21],cnt = 1; inline void insert(int x) { int cur = 1; for(int i=20;i>=0;i--) { int res = 0; if(x & (1<<i)) res = 1; tot[cur]++; if(!Trie[cur][res]) Trie[cur][res] = ++cnt,cur = cnt; else cur = Trie[cur][res]; } tot[cur]++; return; } inline int query(int x) { int cur = 1,res = 0; for(int i=20;i>=0;i--) { int now = 0; if(x & (1<<i)) now ^= 1; if(!Trie[cur][now]) return res; if(tot[Trie[cur][now]] < (1 << (i))) cur = Trie[cur][now]; else cur = Trie[cur][now^1],res |= (1<<i); } return res; } int main() { n = read(),m = read(); for(int i=1;i<=n;i++) {int x = read();if(!used[x]) insert(x),used[x]=1;} int x = 0; for(int i=1;i<=m;i++) { x ^= read(); printf("%d\n",query(x)); } }