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 }
codeforces 842 D. Vitya and Strange Lesson
posted @ 2018-08-17 16:30  KingSann  阅读(181)  评论(0编辑  收藏  举报