Codeforces 948D Perfect Security

Perfect Security

题意:给你一个A[i]数组, 再给你一个B[i]数组, 现在用选取 B[i] 数组中的一个 去和 A[i] 数组里的一个元素去进行异或操作, B[i]数组的元素只能用一次,现在求A[i]数组异或后的最小字典序。

题解:将B[I]数组按照2进制分解之后开一个字典树, 然后匹配每个A[i]中的元素就好了。

代码:

 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 = 300010;
15 int tree[N*32][2];
16 int cnt[N*32];
17 int tot = 2;
18 void Insert(int tmp){
19     int rt = 1;
20     for(int i = 30; i >= 0; i--){
21         int id = (tmp>>i)&1;
22         if(tree[rt][id] == 0) tree[rt][id] = tot++;
23         cnt[tree[rt][id]]++;
24         rt = tree[rt][id];
25     }
26 }
27 int Find(int tmp){
28     int rt = 1;
29     int ret = 0;
30     for(int i = 30; i >= 0; i--){
31         int id = (tmp>>i)&1;
32         if(cnt[tree[rt][id]] >= 1) {
33             cnt[tree[rt][id]]--;
34             rt = tree[rt][id];
35         }
36         else{
37             ret += 1<<i;
38             cnt[tree[rt][!id]]--;
39             rt = tree[rt][!id];
40         }
41     }
42     return ret;
43 }
44 int a[N], b[N];
45 int main(){
46     int n;
47     scanf("%d",&n);
48     for(int i = 1; i <= n; i++) scanf("%d", &a[i]);
49     for(int i = 1; i <= n; i++) {
50             scanf("%d", &b[i]);
51             Insert(b[i]);
52     }
53     for(int i = 1; i <= n; i++){
54         printf("%d%c",Find(a[i])," \n"[i == n]);
55     }
56     return 0;
57 }
View Code

 

posted @ 2018-04-03 15:59  Schenker  阅读(145)  评论(0编辑  收藏  举报