Codeforces 706D Vasiliy's Multiset
题意: 给你一个可以有重复元素的集合, '+'表示这个往这个集合里添加某个元素, '-' 表示删除某个集合中的元素(确保有了才会进行删除操作), ’?' 表示询问操作, 问在这个集合中对这个元素进行异或操作的最大异或值是多少, 注意的是 这个集合有一个初始值0。
题解:和前几个题目一样, 还是将这个数转换成2进制, 然后从高位往低位进行匹配相反的值。
代码:
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define LL long long 4 #define ULL unsigned LL 5 #define fi first 6 #define se second 7 #define lson l,m,rt<<1 8 #define rson m+1,r,rt<<1|1 9 #define max3(a,b,c) max(a,max(b,c)) 10 #define min3(a,b,c) min(a,min(b,c)) 11 const int INF = 0x3f3f3f3f; 12 const LL mod = 1e9+7; 13 typedef pair<int,int> pll; 14 const int N = 1e7+10; 15 int trie[N][2]; 16 int cnt[N*2]; 17 int tot = 2; 18 void Insert(int tmp, int c){ 19 int rt = 1; 20 for(int i = 31; i >= 0; i--){ 21 int id = (tmp>>i) & 1; 22 if(trie[rt][id] == 0) trie[rt][id] = tot++; 23 rt = trie[rt][id]; 24 cnt[rt] += c; 25 } 26 } 27 int Find(int tmp){ 28 int rt = 1, ret = 0; 29 for(int i = 31; i >= 0; i--){ 30 int id = (tmp>>i) & 1; 31 if(cnt[trie[rt][!id]] >= 1) { 32 ret += (1<<i); 33 rt = trie[rt][!id]; 34 } 35 else rt = trie[rt][id]; 36 } 37 return ret; 38 } 39 int main(){ 40 41 int t; 42 scanf("%d", &t); 43 char s[2]; int tmp; 44 Insert(0,1); 45 while(t--){ 46 scanf("%s %d", s, &tmp); 47 if(s[0] == '+') Insert(tmp, 1); 48 else if(s[0] == '-') Insert(tmp, -1); 49 else printf("%d\n", Find(tmp)); 50 } 51 return 0; 52 }