three arrays
[Time Limit: 2500 ms quad Memory Limit: 262144 kB
]
题意
给出 (a),(b) 数组,定义数组 (c[i] = a[i] XOR b[i]),现在可以任意调整 (a) 和 (b) 的顺序,使得最后的 (c) 字典序最小。
思路
对于 (a) 数组和 (b) 数组分别建立字典树,然后从大到小在字典树上贪心构造尽量小的 (c)。
对于某一位,如果两颗树上同时有 (00) 或者 (11),那么就选择往这样的边 (dfs),否则的话往 (01) 或者 (10) 去 (dfs),并加上这一位的异或值。
因为 (01) 和 (10) 不可能同时出现,因为如果同时出现了,肯定优先去 (00) 或者 (11)。那么就是 (00) 和 (11) 的情况,可能出现往 (00) 的答案是 (4),往 (11) 的答案是 (3),那么无法让小的先出来,所以可以任一选一个走,把另一个留到后面走,然后对于所有求出来的 (c) 在 (sort) 一遍。
/***************************************************************
> File Name : a.cpp
> Author : Jiaaaaaaaqi
> Created Time : Fri 06 Sep 2019 09:17:26 PM CST
***************************************************************/
#include <map>
#include <set>
#include <list>
#include <ctime>
#include <cmath>
#include <stack>
#include <queue>
#include <cfloat>
#include <string>
#include <vector>
#include <cstdio>
#include <bitset>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#define lowbit(x) x & (-x)
#define mes(a, b) memset(a, b, sizeof a)
#define fi first
#define se second
#define pb push_back
#define pii pair<int, int>
typedef unsigned long long int ull;
typedef long long int ll;
const int maxn = 1e5 + 10;
const int maxm = 1e5 + 10;
const ll mod = 1e9 + 7;
const ll INF = 1e18 + 100;
const int inf = 0x3f3f3f3f;
const double pi = acos(-1.0);
const double eps = 1e-8;
using namespace std;
int n, m;
int cas, tol, T;
int tot[2];
int a[maxn], b[maxn], c[maxn];
int node[2][maxn*30][2], cnt[2][maxn*30];
void insert(int x, int id) {
int rt = 0;
for(int i=30; i>=1; i--) {
int f = (x&(1<<(i-1))) ? 1 : 0;
if(node[id][rt][f] == 0) {
tot[id]++;
mes(node[id][tot[id]], 0);
cnt[id][tot[id]] = 0;
node[id][rt][f] = tot[id];
}
rt = node[id][rt][f];
cnt[id][rt]++;
}
}
int dfs(int rt1, int rt2, int p) {
// printf("rt1=%d rt2=%d
", rt1, rt2);
if(p == 0) return 0;
bool ok00 = (node[0][rt1][0] && cnt[0][node[0][rt1][0]]);
bool ok01 = (node[0][rt1][1] && cnt[0][node[0][rt1][1]]);
bool ok10 = (node[1][rt2][0] && cnt[1][node[1][rt2][0]]);
bool ok11 = (node[1][rt2][1] && cnt[1][node[1][rt2][1]]);
if(ok00 && ok10) {
cnt[0][node[0][rt1][0]]--, cnt[1][node[1][rt2][0]]--;
return dfs(node[0][rt1][0], node[1][rt2][0], p-1);
} else if(ok01 && ok11) {
cnt[0][node[0][rt1][1]]--, cnt[1][node[1][rt2][1]]--;
return dfs(node[0][rt1][1], node[1][rt2][1], p-1);
} else if(ok00 && ok11) {
cnt[0][node[0][rt1][0]]--, cnt[1][node[1][rt2][1]]--;
return dfs(node[0][rt1][0], node[1][rt2][1], p-1) + (1<<(p-1));
} else {
cnt[0][node[0][rt1][1]]--, cnt[1][node[1][rt2][0]]--;
return dfs(node[0][rt1][1], node[1][rt2][0], p-1) + (1<<(p-1));
}
}
int main() {
// freopen("in", "r", stdin);
scanf("%d", &T);
while(T--) {
cnt[0][0] = cnt[1][0] = tot[0] = tot[1] = 0;
mes(node[0][0], 0), mes(node[1][0], 0);
scanf("%d", &n);
for(int i=1; i<=n; i++) scanf("%d", &a[i]), insert(a[i], 0);
for(int i=1; i<=n; i++) scanf("%d", &b[i]), insert(b[i], 1);
for(int i=1; i<=n; i++) c[i] = dfs(0, 0, 30);
sort(c+1, c+1+n);
for(int i=1; i<=n; i++) printf("%d%c", c[i], i==n ? '
' : ' ');
}
return 0;
}