Codeforces 948D 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 }