codeforces 842 D. Vitya and Strange Lesson
给定$n$个数字,分别为$a_1, a_2, \dots , a_n$
有若干次操作,每次给定一个$x$,并将所有的$a_i$变为$a_i \oplus x$,之后询问$\mathop{mex}\{a_1,a_2, \dots , a_n\}$
01trie维护数字,然后全部异或相当于在二进制下为1的位置进行子树交换,打上标记就没了……
1 #include <bits/stdc++.h> 2 using namespace std; 3 const int N = 1e6 + 10; 4 int n, m; 5 6 int cnt[N], ch[N][2], tot = 1, tag, a[N]; 7 8 void ins(int val) { 9 int x = 1; 10 for(int i = 20 ; ~ i ; -- i) { 11 ++ cnt[x]; 12 int c = (val >> i) & 1; 13 if(!ch[x][c]) ch[x][c] = ++ tot; 14 x = ch[x][c]; 15 } 16 ++ cnt[x]; 17 } 18 19 int query() { 20 int res = 0, x = 1, l = 0, r = (1 << 21) - 1; 21 for(int i = 20 ; ~ i ; -- i) { 22 int bit = (tag >> i) & 1; 23 int lc = ch[x][bit], rc = ch[x][!bit]; 24 int mid = (l + r) >> 1; 25 if(cnt[lc] == mid - l + 1) x = rc, l = mid + 1, res |= 1 << i; 26 else x = lc, r = mid; 27 } 28 return res; 29 } 30 31 int main() { 32 scanf("%d%d", &n, &m); 33 for(int i = 1 ; i <= n ; ++ i) scanf("%d", &a[i]); 34 sort(a + 1, a + 1 + n); 35 n = unique(a + 1, a + 1 + n) - a - 1; 36 for(int i = 1 ; i <= n ; ++ i) ins(a[i]); 37 for(int i = 1, x ; i <= m ; ++ i) { 38 scanf("%d", &x); 39 tag ^= x; 40 printf("%d\n", query()); 41 } 42 }